web-dev-qa-db-ja.com

Bash:構文エラー:予期しないリダイレクト

私はスクリプトでこれを行います:

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)

私は別のスーズマシンでこのエラーを受け取りませんが:

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

なぜエラーですか?

118
Open the way

あなたのスクリプトは、そのハッシュバンラインで/bin/bashまたは/bin/shを参照していますか? Ubuntuのデフォルトのシステムシェルは bash ではなく dash であるため、#!/bin/shがある場合、スクリプトは予想とは異なるシェルを使用します。ダッシュには<<<リダイレクト演算子がありません。

199
John Kugelman

Docker:

私は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)"]

eachパラメーターを囲む引用符に注意してください。

11
kemicofa

そのコマンドの出力を取得して、変数に入れることができます。次に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!
3
AmirHossein

次を使用してスクリプトを実行している場合:

Sudo sh ./script.sh

次に、代わりに次を使用します。

Sudo bash ./script.sh

これは、BashがUbuntuのデフォルトのシェルではないためです。そのため、「sh」を使用すると、デフォルトのシェルが使用されます。これは実際にはダッシュです。これは、スクリプトの先頭に#!/bin/bashがあるかどうかに関係なく起こります。その結果、上記のようにbashを使用するよう明示的に指定する必要があり、スクリプトは予想どおりに実行されるはずです。

DashはBashと同じリダイレクトをサポートしていません。

3

より簡単な方法で、

direc=$(basename `pwd`)

または、シェルを使用します

$ direc=${PWD##*/}
2
ghostdog74

エラーのもう1つの理由は、Subversion作業コピーを更新するcronジョブを実行していて、更新後に競合状態にあるバージョン対応スクリプトを実行しようとした場合です。

1
Motin

私の場合、エラーは「>>」を2回入れたためです。

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
Mansur Ali

スクリプトを実行する前に、インタープリターのシェルスクリプトの最初の行を確認する必要があります。

例:スクリプトが/ bin/bashで始まる場合、以下のコマンド「bash script_name.sh」を使用してスクリプトを実行します

スクリプトが/ bin/shで始まる場合、以下のコマンド「sh script_name.sh」を使用してスクリプトを実行します

./sample.sh-スクリプトの最初の行からインタープリターを検出して実行します。

デフォルトとして異なるシェルを持つ異なるLinuxディストリビューション。

0
SjK

私のマシンでは、スクリプトを直接実行する場合、デフォルトはbashです。

Sudoで実行した場合、デフォルトはshです。

そのため、Sudoを使用したときにこの問題が発生していました。

0
Michael Mather