“ -” ใน“ bash -” หมายถึงอะไร?


33

อะไรbash -เฉลี่ยในรหัสเปลือกทุบตีต่อไปนี้หรือไม่? ดูเหมือนว่าจะใช้ในการส่งออกรหัสสุดท้ายเป็นอินพุท ถ้าเป็นเช่นนั้นฉันจะเขียนมันเป็นbashหรือxargs bash?

curl --silent --location https://rpm.nodesource.com/setup | bash -

คำตอบ:


36

เมื่อสงสัยให้อ่านซอร์สโค้ด =)

Bash 4.3, shell.cline 830, ในฟังก์ชั่นparse_shell_options() :

  /* A single `-' signals the end of options.  From the 4.3 BSD sh.
     An option `--' means the same thing; this is the standard
     getopt(3) meaning. */
  if (arg_string[0] == '-' &&
       (arg_string[1] == '\0' ||
         (arg_string[1] == '-' && arg_string[2] == '\0')))
    return (next_arg);

ในคำอื่น ๆ ที่-จะบอกว่ามีไม่มีตัวเลือกมากขึ้น ถ้ามีคำพูดใด ๆ -เพิ่มเติมในบรรทัดคำสั่งพวกเขาจะได้รับการปฏิบัติเป็นชื่อไฟล์แม้ว่าคำว่าเริ่มต้นด้วย

ในตัวอย่างของคุณแน่นอนว่า-มีการซ้ำซ้อนอย่างสมบูรณ์เนื่องจากไม่มีสิ่งใดติดตามอยู่ดี ในคำอื่น ๆเป็นสิ่งที่เทียบเท่ากับbash -bash


Bash ใช้คำสั่งของมัน

  1. จากไฟล์สคริปต์หากมีการระบุไว้ในบรรทัดคำสั่งหรือ
  2. ไม่ใช่การโต้ตอบจาก stdin หาก stdin ไม่ใช่ TTY (เช่นในตัวอย่างของคุณ: stdin เป็นไพพ์ดังนั้น Bash จะดำเนินการเนื้อหาของ URL นั้นเป็นสคริปต์) หรือ
  3. แบบโต้ตอบหาก stdin เป็น TTY

มันเป็นความเข้าใจผิดที่bash -บอกให้ Bash อ่านคำสั่งจากอินพุตมาตรฐาน ในขณะที่มันเป็นความจริงที่ว่าในตัวอย่างของคุณ, ทุบตีจะอ่านคำสั่งจาก stdin ก็จะได้ทำอย่างนั้นไม่ว่าจะมี-ในบรรทัดคำสั่งเพราะตามที่ระบุไว้ข้างต้นคือการเหมือนกันbash -bash

หากต้องการแสดงเพิ่มเติม-ว่าไม่ได้หมายความว่า stdin ให้พิจารณา:

  • catคำสั่งถูกออกแบบมาเพื่อตีความ-เป็น stdin ตัวอย่างเช่น:

    $ echo xxx | cat /etc/hosts - /etc/shells
    127.0.0.1 localhost
    xxx
    # /etc/shells: valid login shells
    /bin/sh
    /bin/dash
    /bin/bash
    /bin/rbash
    /bin/zsh
    /usr/bin/zsh
    /usr/bin/screen
    /bin/tcsh
    /usr/bin/tcsh
    /usr/bin/tmux
    /bin/ksh93
  • ในทางตรงกันข้ามคุณไม่สามารถได้รับการทุบตีในการดำเนินการ/bin/dateแล้ว/bin/hostnameโดยพยายามนี้:

    $ echo date | bash - hostname
    /bin/hostname: /bin/hostname: cannot execute binary file

    ค่อนข้างจะพยายามตีความ/bin/hostnameว่าเป็นไฟล์สคริปต์เชลล์ซึ่งล้มเหลวเนื่องจากเป็นไฟล์ไบนารีไบนารี

  • คุณไม่สามารถดำเนินการdate +%sโดยใช้bash -อย่างใดอย่างหนึ่ง

    $ date +%s
    1448696965
    $ echo date | bash -
    Sat Nov 28 07:49:31 UTC 2015
    $ echo date | bash - +%s
    bash: +%s: No such file or directory

คุณเขียนxargs bashแทนได้ไหม ไม่ curl | xargs bashต้องเรียกใช้ bash พร้อมเนื้อหาของสคริปต์เป็นอาร์กิวเมนต์บรรทัดคำสั่ง คำแรกของเนื้อหาจะเป็นอาร์กิวเมนต์แรกและอาจถูกตีความผิดว่าเป็นชื่อไฟล์สคริปต์


6
upvote สำหรับคำตอบที่ถูกต้องเท่านั้น
geirha

อันที่จริง: ในคำพูดของ manpageAn argument of - is equivalent to --.
steeldriver

หากคุณต้องการใช้จริงๆxargsแทนจะสามารถใช้งานได้ (ในสถานการณ์ที่ จำกัด ของสคริปต์อินพุตที่มีขนาดเล็ก) ด้วย| xargs bash -c; xargsแต่จริงๆนี้ไม่ได้ใช้ประโยชน์หรือสำนวนของ
tripleee

@tripleee หากเนื้อหาของ URL มีอะไรมากกว่าหนึ่งซับแล้วการแบ่งบรรทัดและตัวคั่นอื่น ๆ อาจจะผิดทั้งหมด
200_success

แน่นอนคุณพูดถูก
tripleee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.