배쉬 : 구문 오류 : 예기치 않은 리디렉션


138

스크립트에서이 작업을 수행합니다.

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

그리고 나는 얻는다 :

Syntax error: redirection unexpected

우분투 머신에서

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

왜 오류가 발생합니까?


참고로이 명령은 cygwin에서도 작동합니다 (/ bin / bash --version GNU bash, 버전 3.2.49 (23)-릴리스 (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
hlovdal

답변:


243

스크립트 참조합니까 /bin/bash또는 /bin/sh해시 뱅 라인? 우분투의 기본 시스템 쉘은 bash가 아닌 dash 이므로 스크립트가 예상과 다른 쉘을 사용합니다. 대시에는 리디렉션 연산자 가 없습니다 .#!/bin/sh<<<


14

도커 :

내가했던 것처럼 Dockerfile 에서이 문제가 발생했습니다.

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

그러나이 문제 에 따라 해결되었습니다.

간부 형태는 가능 쉘 문자열 munging을 피하고,에 할 수 있습니다 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가 우분투의 기본 쉘이 아니기 때문입니다. 따라서 "sh"를 사용하면 기본 쉘만 사용됩니다. 실제로 대시입니다. #!/bin/bash스크립트 상단에 있는지 여부에 관계없이 발생합니다 . 결과적으로 bash위에 표시된대로 사용하도록 명시 적으로 지정 해야하며 스크립트가 예상대로 실행되어야합니다.

대시는 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

오류의 또 다른 이유는 하위 버전 작업 복사본을 업데이트하는 크론 작업을 실행하고 업데이트 후 충돌 상태 인 버전이 지정된 스크립트를 실행하려고 한 경우 일 수 있습니다.


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

내가 여기서 해결책을 설명했다고 생각하지 않습니까?
Sijeesh

8 년 전에 작성된 John Kugelman의 답변 에서 적절하게 다루지 않은 내용이 있습니까?
Toby Speight
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.