Bash: Помилка синтаксису: переадресація несподівана


138

Я роблю це за сценарієм:

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

і я отримую:

Syntax error: redirection unexpected

в машині ubuntu

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

поки я не отримую цієї помилки в іншій машині suse:

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

Чому помилка?


Для довідки, команда працює і на cygwin (/ bin / bash --версія GNU bash, версія 3.2.49 (23) -випуск (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
hlovdal

Відповіді:


243

Чи посилається на ваш сценарій /bin/bashабо /bin/shв його хеш-рядок? Системна оболонка за замовчуванням в Ubuntu - тире , а не bash , тому якщо у вас є, #!/bin/shто ваш сценарій буде використовувати іншу оболонку, ніж ви очікували. Dash не має <<<оператора перенаправлення.


14

Докер:

Я отримував цю проблему з мого Dockerfile, як у мене було:

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

Однак відповідно до цього питання було вирішено:

Форма exec дозволяє уникнути змінення рядка оболонки та RUN команд із використанням базового зображення, яке не містить /bin/sh.

Примітка

Для використання іншої оболонки, крім /bin/sh, використовуйте форму exec, що передається в потрібну оболонку. Наприклад,

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

Рішення:

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

Помітьте лапки навколо кожного параметра.


14

Якщо для запуску сценарію використовується таке:

sudo sh ./script.sh

Тоді вам потрібно буде скористатися наступним:

sudo bash ./script.sh

Причиною цього є те, що Bash не є оболонкою для Ubuntu за замовчуванням. Отже, якщо ви використовуєте "sh", тоді він буде просто використовувати оболонку за замовчуванням; що насправді тире. Це станеться незалежно від того, якщо ви #!/bin/bashзнаходитесь у верхній частині сценарію. Як результат, вам потрібно буде чітко вказати, як використовувати, bashяк показано вище, і ваш сценарій повинен працювати при очікуванні.

Dash не підтримує переспрямування так само, як Bash.


6

Ви можете отримати вихід цієї команди і помістити її в змінну. потім використовуйте heredoc. наприклад:

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

можна записати так:

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

і ось так (це те, що ви хочете):

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

Практичний приклад busyboxпід dockerконтейнером:

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!

... або echo 'text' | ncяка ще коротша.
phil294

2

зробити це простіше,

direc=$(basename `pwd`)

Або скористайтеся оболонкою

$ direc=${PWD##*/}

1

Іншою причиною помилки може бути, якщо ви виконуєте завдання cron, яке оновлює робочу копію субверсії, а потім намагається запустити розроблений сценарій, який після оновлення був у конфліктному стані ...


1

На моїй машині, якщо я запускаю сценарій безпосередньо, за замовчуванням є bash.

Якщо я запускаю його sudo, за замовчуванням є sh.

Ось чому я вражав цю проблему, коли використовував sudo.


0

У моєму випадку помилка полягає в тому, що я двічі поставив ">>"

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

я просто виправлю це як

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

0

Перш ніж запустити скрипт, слід перевірити інтерпретатор першого рядка сценарію оболонки.

Наприклад: якщо сценарії починаються з / bin / bash, запустіть скрипт за допомогою команди нижче "bash script_name.sh"

якщо скрипт починається з / bin / sh, запустіть сценарій за допомогою команди нижче "sh script_name.sh"

./sample.sh - це виявить інтерпретатора з першого рядка сценарію та запустіть.

Різні дистрибутиви Linux, які за замовчуванням мають різні оболонки.


1
Хоча ми дякуємо вам за вашу відповідь, було б краще, якби вона надала додаткову цінність поверх інших відповідей. У цьому випадку ваша відповідь не надає додаткового значення, оскільки інший користувач вже розмістив це рішення. Якщо попередня відповідь була вам корисною, вам слід проголосувати за неї, а не повторювати ту саму інформацію.
Toby Speight

Ви не думаєте, що я пояснив це рішення прикладом?
Сієєш

Чи є тут щось, що недостатньо висвітлено у відповіді Джона Кугельмана, написаній 8 років тому?
Toby Speight
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.