Bash: Lỗi cú pháp: chuyển hướng bất ngờ


137

Tôi làm điều này trong một kịch bản:

read direc <<< $(basename `pwd`)

va tôi lây:

Syntax error: redirection unexpected

trong một máy Ubuntu

/bin/bash --version
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)

trong khi tôi không gặp lỗi này trong một máy suse khác:

/bin/bash --version
GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

Tại sao có lỗi?


Để tham khảo, lệnh này cũng hoạt động trên cygwin (/ bin / bash --version GNU bash, phiên bản 3.2.49 (23) -release (i686-pc-cygwin) Bản quyền (C) 2007 Free Software Foundation, Inc.)
hlovdal 17/03/2016

Câu trả lời:


242

Tập lệnh của bạn tham chiếu /bin/bashhoặc /bin/shtrong dòng băm bang của nó? Shell hệ thống mặc định trong Ubuntu là dấu gạch ngang , không phải bash , vì vậy nếu bạn có #!/bin/shthì tập lệnh của bạn sẽ sử dụng một trình bao khác so với bạn mong đợi. Dash không có <<<toán tử chuyển hướng.


14

Docker:

Tôi đã gặp vấn đề này từ Dockerfile của tôi như tôi đã có:

RUN bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

Tuy nhiên, theo vấn đề này , nó đã được giải quyết:

Biểu mẫu exec giúp có thể tránh được việc trộn chuỗi shell và RUN các lệnh sử dụng hình ảnh cơ sở không chứa /bin/sh.

Ghi chú

Để sử dụng một shell khác /bin/sh, ngoài việc sử dụng biểu mẫu exec trong shell mong muốn. Ví dụ,

RUN ["/bin/bash", "-c", "echo hello"]

Giải pháp:

RUN ["/bin/bash", "-c", "bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)"]

Lưu ý các trích dẫn xung quanh mỗi tham số.


14

Nếu bạn đang sử dụng cách sau để chạy tập lệnh của mình:

sudo sh ./script.sh

Sau đó, bạn sẽ muốn sử dụng như sau:

sudo bash ./script.sh

Lý do cho điều này là Bash không phải là vỏ mặc định cho Ubuntu. Vì vậy, nếu bạn sử dụng "sh" thì nó sẽ chỉ sử dụng shell mặc định; đó thực sự là Dash. Điều này sẽ xảy ra bất kể bạn có #!/bin/bashở đầu tập lệnh của mình không. Do đó, bạn sẽ cần chỉ định rõ ràng để sử dụng bashnhư được hiển thị ở trên và tập lệnh của bạn sẽ chạy theo dự kiến.

Dash không hỗ trợ chuyển hướng giống như Bash.


6

Bạn có thể lấy đầu ra của lệnh đó và đặt nó vào một biến. sau đó sử dụng heredoc. ví dụ:

nc -l -p 80 <<< "tested like a charm";

có thể được viết như sau:

nc -l -p 80 <<EOF
tested like a charm
EOF

và như thế này (đây là những gì bạn muốn):

text="tested like a charm"
nc -l -p 80 <<EOF
$text
EOF

Ví dụ thực tế trong busyboxdưới dockercontainer:

kasra@ubuntu:~$ docker run --rm -it busybox
/ # nc -l -p 80 <<< "tested like a charm";
sh: syntax error: unexpected redirection


/ # nc -l -p 80 <<EOL
> tested like a charm
> EOL
^Cpunt!       => socket listening, no errors. ^Cpunt! is result of CTRL+C signal.


/ # text="tested like a charm"
/ # nc -l -p 80 <<EOF
> $text
> EOF
^Cpunt!

... hoặc echo 'text' | ncthậm chí còn ngắn hơn.
phil294

2

làm theo cách đơn giản hơn,

direc=$(basename `pwd`)

Hoặc sử dụng vỏ

$ direc=${PWD##*/}

1

Một lý do khác cho lỗi có thể là nếu bạn đang chạy một công việc định kỳ cập nhật một bản sao làm việc lật đổ và sau đó đã cố chạy một tập lệnh được phiên bản ở trạng thái xung đột sau khi cập nhật ...


1

Trên máy của tôi, nếu tôi chạy tập lệnh trực tiếp, mặc định là bash.

Nếu tôi chạy nó với sudo, mặc định là sh.

Đó là lý do tại sao tôi gặp phải vấn đề này khi tôi sử dụng sudo.


0

Trong trường hợp của tôi, lỗi là do tôi đã đặt ">>" hai lần

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> >> $LOG_PATH

tôi chỉ sửa nó là

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH

0

Trước khi chạy tập lệnh, bạn nên kiểm tra dòng đầu tiên của tập lệnh shell cho trình thông dịch.

Ví dụ: nếu tập lệnh bắt đầu bằng / bin / bash, hãy chạy tập lệnh bằng lệnh bên dưới "bash script_name.sh"

nếu tập lệnh bắt đầu bằng / bin / sh, hãy chạy tập lệnh bằng lệnh bên dưới "sh script_name.sh"

./sample.sh - Điều này sẽ phát hiện trình thông dịch từ dòng đầu tiên của tập lệnh và chạy.

Các bản phân phối Linux khác nhau có các shell khác nhau làm mặc định.


1
Mặc dù chúng tôi cảm ơn bạn vì câu trả lời của bạn, nhưng sẽ tốt hơn nếu nó cung cấp giá trị bổ sung trên đầu các câu trả lời khác. Trong trường hợp này, câu trả lời của bạn không cung cấp giá trị bổ sung, vì một người dùng khác đã đăng giải pháp đó. Nếu một câu trả lời trước đó hữu ích cho bạn, bạn nên bỏ phiếu thay vì lặp lại thông tin tương tự.
Toby Speight

Bạn không nghĩ rằng tôi đã giải thích giải pháp ở đây với một ví dụ?
Sijeesh

Có điều gì ở đây không được đề cập đầy đủ trong câu trả lời của John Kugelman được viết 8 năm trước không?
Toby Speight
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.