bash : 나쁜 대체


148
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}

이 bash 스크립트는 Ubuntu에서 잘못된 대체 오류를 발생시킵니다. 도움을 주시면 감사하겠습니다.


그것은 나에게 잘 작동하고 있습니다. 무엇을 이루려고 노력하고 있습니까?
— fedorqui 'SO 중지 피해'12

작업 이름을 job_201312161447과 0003으로 나누려고합니다. 우분투 에서이 작업을 실행하려고 할 때만이 오류가 발생합니다.
— Arindam Choudhury

음 이상하다. 사용하면 cut어떻게 되나요? cut -d_ -f1,2 <<< "$jobname"그리고 cut -d_ -f3 <<< "$jobname"그것을 만들
— fedorqui 'SO 그만 해'12

감사. 그런데 왜 jobname_pre = $ {작업 이름 : 0 : 16} 오류 준
— Arindam Choudhury의

1
@bludger 당신이 맞아, 당신이 sh script.sh그것을하면 "나쁜 대체"오류가 발생하는 것을 볼 수 있습니다 .
— fedorqui 'SO 중지 피해'12

답변:


200

/bin/sh우분투 아래 의 기본 쉘 ( )은 dash아닌을 가리 킵니다 bash.

me@pc:~$ readlink -f $(which sh)
/bin/dash

따라서을 사용 chmod +x your_script_file.sh하여 실행하거나을 사용하여 ./your_script_file.sh실행하면 bash your_script_file.sh제대로 작동합니다.

sh your_script_file.shhashbang 행이 무시되고 스크립트가 dash해당 문자열 대체 구문을 지원하지 않는 로 해석되므로이 스크립트를 실행하면 작동 하지 않습니다.


2
그는 /bin/bash당신의 대답이 맞지 않도록 사용 하고 있습니까?! 당신은 어디에서 그가 사용하고 읽습니까 /bin/sh이나 sh script.sh?
— Daniel W.

4
@DanFromGermany 그 이유는 그 오류의 유일한 이유입니다. 즉, 그는 hashbang을 고려하지 않는 방식으로 스크립트를 실행하고 있으며 다른 셸 (대시 대시)에서 bash 구문이 지원되지 않습니다. 질문에 항상 필요한 세부 사항이 모두 포함되어있는 것은 아니며 점에 합류해야합니다. 어쨌든 내 대답을 자유롭게 내리십시오.
— Vanni Totaro

2
공감할 필요가 없습니다. 동일한 오류 메시지가 bad substitution있으며 정보를 수집하려고하는데 정보가 너무 적기 때문에이 질문은 도움이되지 않습니다.
— Daniel W.

2
@ DanFromGermany 당신은 당신 자신의 질문을 게시하려고 시도 할 수 있습니다. 아마도 똑같은 문제는 아닙니다.
— Vanni Totaro

69

나는 같은 문제가 있었다. 스크립트에없는 것이 있는지 확인하십시오

#!/bin/sh 

스크립트 상단에 대신에

#!/bin/bash

5
내가 사용 #!bin/bash하고 sh script.sh아직도 나에게 오류 메시지를 주었다. 그런 다음 ./script.sh작동합니다.
— whyisyoung

파일에 상단에 shebang이 없으면 추가로 불량 대체가#!/bin/bash 수정됩니다 .
— Jamie

1
@whyisyoung 변수 이름에 점 (.)이있을 수 있습니다. 그것은 나쁜 미묘한 것을 제공합니다. 오류.
— user13107

4
@whyisyoung #!줄은 스크립트를 직접 실행할 때만 사용됩니다. sh script.sh라인 을 사용 하면 완전히 무시됩니다.
— bfontaine

35

여기에 도착하는 다른 사람들에게는 명령에 env 변수 구문을 사용할 때 정확한 메시지가 ${which sh}아닌 정확한 메시지가 나타납니다.$(which sh)


21

스크립트 구문은 유효한 bash이며 좋습니다.

실패의 가능한 원인 :

  1. 당신 bash은 실제로 bash가 아니지만 kshbash의 매개 변수 대체를 이해하지 못하는 다른 쉘입니다. 스크립트가 잘 보이고 bash와 함께 작동하기 때문입니다. 수행 ls -l /bin/bash하고 정말 bash에 그리고 다른 쉘에 연결된 SYM 확인하세요.

  2. 시스템에 bash가 있으면 스크립트를 잘못된 방식으로 실행할 수 있습니다. ksh script.sh또는 sh script.sh기본 쉘은 bash가 아닙니다. 당신은 적절한 shebang을 가지고 있기 때문에, bash가 ./script.sh있거나 bash ./script.sh괜찮다면.


7
/bin/bash(가 아닌 /bin/sh)이 다른 쉘에 연결되어 있으면 놀랍습니다 .
— chepner

ksh는 실제로 대부분의 bash 구문 확장이 시작된 곳입니다. 그것은 확실히 문제의 특정 매개 변수 확장 구문을 가지고있다. 나는 그것을 가능하지 않을 쉘로 부르는 것을 제안하지 않는 경향이 있습니다.
— Charles Duffy

7

스크립트를 실행 파일로 실행하는 대신 bash 명령을 사용하여 명시 적으로 스크립트를 실행하십시오.


3
좋아요 사용함으로써,보다 명확하게하기 위해 일부 샘플 출력을 추가하는 것이 도움이 될 것입니다 sh script및 bash script... 나의 제안 :
— fedorqui은 'SO 해치지 중지'

4

또한 스크립트의 첫 줄에 빈 문자열이 없는지 확인하십시오.

즉 #!/bin/bash, 스크립트의 첫 번째 줄 인지 확인하십시오 .


3

귀하의 예와 관련이 없지만 Bad substitutionBash가 인식하지 못하는 대체 구문에 대해 Bash에서 오류가 발생할 수도 있습니다 . 이것은 다음과 같을 수 있습니다 :

  • 길쭉한 공백. 예 :bash -c '${x }'
  • 오타. 예 :bash -c '${x;-}'
  • 최신 Bash 버전에 추가 된 기능입니다. 예 bash -c '${x@Q}'를 들어 Bash 4.4.

동일한 식에 여러 개의 치환이있는 경우 Bash는 문제가있는 식을 정확히 찾아내는 데 큰 도움이되지 않을 수 있습니다. 예 :

$ bash -c '"${x } multiline string
$y"'
bash: line 1: ${x } multiline string
$y: bad substitution

2
이것은 첫 번째 히트 Bad substitution이므로 우리가 부딪친 사건을 포함시킬 것이라고 생각했습니다. ( @QBash 4.3에서 긴 여러 줄 표현으로 숨어있었습니다.)
— Daniel Darabos

2
Mac에서 Bash 3.x를 실행할 때이 문제가 발생했습니다.
— coloradocolby

2
Prooflink는 에 관한 @Q추가되고 bash-4.4.
— x-yuri

2

bash 또는 dash-모두 작동하지만 구문은 다음과 같아야합니다.

FILENAME=/my/complex/path/name.ext
NEWNAME=${FILENAME%ext}new

1
그것은 완전히 다른 작업입니다. 또한 OP는 소문자 변수 이름을 사용하여 모범 사례를 따르고 있기 때문에 ( pubs.opengroup.org/onlinepubs/9699919799/basedefs/… 참조) 대문자 이름은 OS 또는 셸에 의미가있는 변수에 사용되며 소문자 이름은 응용 프로그램 사용을 위해 예약 됨), 마찬가지로해야합니다.
— Charles Duffy

0

"+ x"가 문제를 일으키는 것 같습니다.

root@raspi1:~# cat > /tmp/btest
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}
root@raspi1:~# chmod +x /tmp/btest
root@raspi1:~# /tmp/btest
root@raspi1:~# sh -x /tmp/btest
+ jobname=job_201312161447_0003
/tmp/btest: 4: /tmp/btest: Bad substitution

0

bash에 중괄호가있는 표현식에 달러 기호를 두 번 추가하고있었습니다.

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

대신에

cp -r $PROJECT_NAME ${PROJECT_NAME}2

-1

이 문제는 답변으로 표시되었거나 bash 선언 앞에 줄이나 공백이 있음을 발견했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.