Những gì mà người Hồi giáo - người Hồi giáo có nghĩa là gì?


33

Điều gì có bash -nghĩa trong mã bash sau đây? Nó dường như được sử dụng để lấy đầu ra mã cuối cùng làm đầu vào. Nếu vậy, tôi chỉ có thể viết nó như là bashhay xargs bash?

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

Câu trả lời:


36

Khi nghi ngờ, hãy đọc mã nguồn. =)

Bash 4.3, shell.cdòng 830, trong chức năngparse_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);

Nói cách khác, người -ta nói rằng không còn lựa chọn nào nữa . Nếu có thêm từ nào trên dòng lệnh, chúng sẽ được coi là tên tệp, ngay cả khi từ bắt đầu bằng a -.

Trong ví dụ của bạn, tất nhiên, điều đó -là hoàn toàn dư thừa, vì dù sao cũng không có gì theo sau nó. Nói cách khác, bash -chính xác là tương đương vớibash .


Bash nhận lệnh của nó

  1. từ tệp tập lệnh nếu nó được cung cấp trên dòng lệnh hoặc
  2. không tương tác từ stdin của nó nếu stdin của nó không phải là TTY (chẳng hạn như trong ví dụ của bạn: stdin là một đường ống, vì vậy Bash sẽ thực thi nội dung của URL đó dưới dạng tập lệnh) hoặc
  3. tương tác nếu stdin của nó là một TTY.

Đó là một quan niệm sai lầm khi bash -bảo Bash đọc các lệnh của nó từ đầu vào tiêu chuẩn của nó. Trong khi nó sự thật rằng trong ví dụ của bạn, Bash sẽ đọc lệnh từ stdin, nó đã có thể làm như vậy cho dù đã có một -trên dòng lệnh, bởi vì, như đã nói ở trên, bash -giống hệt bash.

Để minh họa thêm điều -đó không có nghĩa là stdin, hãy xem xét:

  • Các catlệnh được thiết kế để giải thích một -như stdin. Ví dụ:

    $ 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
    
  • Ngược lại, bạn không thể khiến Bash thực thi /bin/datesau đó /bin/hostnamebằng cách thử điều này:

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

    Thay vào đó, nó cố gắng diễn giải /bin/hostnamenhư một tệp script shell, thất bại bởi vì đó là một nhóm gobbledygook nhị phân.

  • Bạn không thể thực thi date +%sbằng bash -một trong hai.

    $ 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
    

Bạn có thể viết xargs bashthay thế? Số curl | xargs bashsẽ gọi bash với nội dung của tập lệnh dưới dạng đối số dòng lệnh. Từ đầu tiên của nội dung sẽ là đối số đầu tiên và nó có thể bị hiểu sai thành tên tệp kịch bản.


6
upvote cho câu trả lời đúng duy nhất.
geirha

Thật vậy: theo lời của trang chủAn argument of - is equivalent to --.
Steeldo

Nếu bạn thực sự, thực sự muốn sử dụng xargsthay thế, nó sẽ hoạt động (trong kịch bản giới hạn của một tập lệnh đầu vào đủ nhỏ) với | xargs bash -c; nhưng thực sự, đây không phải là một cách sử dụng hữu ích hay thành ngữ xargs.
tripleee

@tripleee Nếu nội dung của URL là bất kỳ thứ gì nhiều hơn một lớp lót, thì dòng ngắt và các dấu phân cách khác có thể sẽ sai.
200_success

Duh, bạn đúng, tất nhiên.
tripleee
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.