서버를 시작하는 명령문을 실행하고 싶습니다. 이를 위해 시작할 서버를 결정하는 환경 변수가 있습니다. 저는 다음 명령을 시작점으로 삼았습니다.
eval "exec gunicorn --chdir /this/dir package.sub:call_main() -b 0.0.0.0:80"
시작해야 할 서버가 여러 개 있으므로 스크립트를 매개변수화하고 싶습니다. 검색을 좀 해보니 그 인용문이 다음과 같다는 것을 알았습니다.추가의. 그래서 내가 지금 가지고 있는 것은 다음과 같습니다.
APP=main
eval exec gunicorn --chdir /this/dir package.sub:call_${APP}() -b 0.0.0.0:80
이상적 syntax error near unexpected token '('
으로는 이와 같은 기본 매개변수를 갖고 싶지만 ${APP:-main}
구문 오류 문제가 해결되면 가능하다고 생각합니다.
위의 진술에 잘못된 것이 있습니까? 또한, eval
여기에는 이것이 필요합니까?exec
답변1
두 번째 코드에서는 매개변수 주위의 큰따옴표를 제거했습니다 eval
. 그러지 마세요. 이를 제거하면 ()
쉘이 특별해집니다(하위 쉘이 시작됨).
대신에:
app=main
eval "exec gunicorn --chdir /this/dir package.sub:call_$app'()' -b 0.0.0.0:80"
eval
문자열을 다시 평가할 때 여기에서 괄호를 인용해야 합니다. $app
호출 전에 변수 확장이 수행됩니다 .eval
또는,
app=main
eval "exec gunicorn --chdir /this/dir 'package.sub:call_$app()' -b 0.0.0.0:80"
이게 더 좋아 보일 수도 있어요.
및 는 변수 이름(예: )에서 유효한 바로 다음 문자를 제외하고 ${APP}
모든 면에서 동일합니다 . 여기서는 필요하지 않습니다. 또한 기존 환경 변수와의 예기치 않은 충돌을 방지하려면 소문자 변수 이름을 사용하십시오.$APP
"${APP}x"
{...}
나는 여기에 필요하지 eval
않다고 생각합니다 exec
. 문자열은 다음을 사용하여 eval
재평가할 필요가 없는 것 같습니다.exec
바꾸다현재 쉘 프로세스 gunicorn
(이것이 당신이 원하는 것인지 모르겠습니다).
충분할 수도
app=main
gunicorn --chdir /this/dir "package.sub:call_$app()" -b 0.0.0.0:80
큰따옴표에 주의하세요.
관련된:
답변2
당신은 복잡한 작업을 수행하고 있습니다. 쉘은 11개의 패스를 만들어야 합니다(그리고 각 패스는 다음 단계를 진행하기 위해 입력을 파괴합니다).
귀하의 코드는
APP=main
eval exec gunicorn --chdir /this/dir package.sub:call_${APP}() -b 0.0.0.0:80
이해하려면 eval을 제거하세요.
exec gunicorn --chdir /this/dir package.sub:call_${APP}() -b 0.0.0.0:80
참고: 첫 번째 예와 유사하게 및 큰따옴표를 제거하면 eval
여전히 동일한 출력을 얻을 수 있습니다.
이제 예약했습니다 ()
(이 경우 토큰이 잘못 해석될 수 없기 때문에 특별합니다. 접두사가 없으면 명령 컨텍스트에 있지 않습니다(따라서 괄호를 사용하여 하위 쉘을 호출함). 참고: 이는 11단계로, 그리고 토큰화 순서를 보면 왜 이런 일이 일어나는지 알 수 있을 것입니다(그리고 쉘 파서는 오래 전에 설계되었으므로 쉽습니다).
따라서 ()를 다음 파서 단계로 전달하도록 쉘에 지시해야 합니다.
이스케이프( )를 사용할 수 있습니다 \
.
exec gunicorn --chdir /this/dir package.sub:call_${APP}\(\) -b 0.0.0.0:80
또는 인용문:
exec gunicorn --chdir /this/dir package.sub:call_${APP}'()' -b 0.0.0.0:80
참고: "단어"(매개변수) 전체를 인용할 필요는 없으며 일부만 인용하면 됩니다. 그러면 작은따옴표가 필요하지 않습니다 ${APP}
(확장 필요).
첫 번째 예에서는 큰따옴표로 인용할 수 있습니다.
eval "exec gunicorn --chdir /this/dir \"package.sub:call_main()\" -b 0.0.0.0:80"
이 방법으로 eval은 외부 따옴표를 제거하고 exec는 내부 따옴표를 봅니다(이스케이프되지 않음).