Bash: синтаксическая ошибка: перенаправление неожиданно

Я делаю это в сценарии:

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

и я получаю:

Syntax error: redirection unexpected

в машине с убунту

/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.

Почему ошибка?

10 ответов

Решение

Ссылка на ваш скрипт /bin/bash или же /bin/sh в его хэш-линии взрыва? Системной оболочкой по умолчанию в Ubuntu является dash, а не bash, так что если у вас есть #!/bin/sh тогда ваш скрипт будет использовать другую оболочку, чем вы ожидаете. Тире не имеет <<< оператор перенаправления.

Если вы используете следующее для запуска вашего скрипта:

sudo sh ./script.sh

Тогда вы захотите использовать следующее:

sudo bash ./script.sh

Причина этого в том, что Bash не является оболочкой по умолчанию для Ubuntu. Итак, если вы используете "sh", то он будет использовать оболочку по умолчанию; который на самом деле Dash. Это произойдет независимо от того, если у вас есть #!/bin/bash в верхней части вашего сценария. В результате вам нужно будет явно указать для использования bash как показано выше, и ваш скрипт должен работать с ожидаемым.

Dash не поддерживает перенаправления так же, как Bash.

Докер:

Я получал эту проблему из моего 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)"]

Обратите внимание на кавычки вокруг каждого параметра.

Вы можете получить вывод этой команды и поместить его в переменную. затем используйте 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!

Сделать это более простым способом,

direc=$(basename `pwd`)

Или используйте оболочку

$ direc=${PWD##*/}

Другая причина ошибки может заключаться в том, что вы запускаете задание cron, которое обновляет рабочую копию Subversion, а затем пытается запустить версионный скрипт, который находился в конфликтном состоянии после обновления...

На моем компьютере, если я запускаю скрипт напрямую, по умолчанию bash,

Если я запускаю его с sudoпо умолчанию sh,

Вот почему я столкнулся с этой проблемой, когда я использовал sudo,

Пункт 1:#!/bin/bash
Пункт 2. Убедитесь, что у вашего файла есть соответствующие разрешения (для примера sh-файлаchmod 777 test.sh)
Пункт 3:./test.sh, не используйsh test.sh

В моем случае ошибка в том, что я поставил ">>" дважды

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

Перед запуском скрипта вы должны проверить первую строку скрипта для интерпретатора.

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

если скрипт начинается с /bin/sh, запустите скрипт с помощью следующей команды "sh script_name.sh"

./sample.sh - это обнаружит интерпретатор из первой строки скрипта и запустится.

Разные дистрибутивы Linux имеют разные оболочки по умолчанию.

Другие вопросы по тегам