Bash에서 명령어의 단일 따옴표 내 변수 확장
나는 단일 따옴표와 변수 안에 다른 명령어가 있는 bash 스크립트에서 명령어를 실행하고 싶습니다.
예repo forall -c '....$variable'
형식으로, 이형으로식,$이스케이프되고 변수가 확장되지 않습니다.
다음과 같은 변형을 시도했지만 거부되었습니다.
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
변수 대신 값을 대입하면 명령이 제대로 실행됩니다.
제가 어디서 잘못되고 있는지 말씀해 주세요.
단일 따옴표 안에 있는 모든 것은 예외 없이 문자 그대로 보존됩니다.
즉, 따옴표를 닫고 무언가를 삽입한 다음 다시 입력해야 합니다.
'before'"$variable"'after'
'before'"'"'after'
'before'\''after'
단어 연결은 단순히 병렬로 이루어집니다.확인할 수 있듯이 위의 각 행은 셸에 대한 단일 단어입니다.따옴표(상황에 따라 단일 따옴표 또는 이중 따옴표)는 단어를 분리하지 않습니다.문자의 을 불가능하게 하기 됩니다.$,;인용에 대한 좋은 튜토리얼은 Mark Reed의 답변을 참조하십시오.관련성:bash에서 이스케이프해야 하는 문자는 무엇입니까?
셸로 해석되는 문자열을 연결하지 않음
변수를 연결하여 셸 명령을 작성하는 것은 절대 피해야 합니다.이것은 SQL 조각의 연결(SQL 주입!)과 유사한 잘못된 생각입니다.
일반적으로 명령에 자리 표시자를 두고, 호출자가 호출 인수 목록에서 해당 자리 표시자를 수신할 수 있도록 변수와 함께 명령을 제공할 수 있습니다.
예를 들어, 다음은 매우 안전하지 않습니다.이러지마세요
script="echo \"Argument 1 is: $myvar\""
/bin/sh -c "$script"
의 $myvar신뢰할 수 없습니다. 다음은 공격입니다.
myvar='foo"; echo "you were hacked'
위의 호출 대신 위치 인수를 사용합니다.다음 호출이 더 낫습니다. 공격할 수 없습니다.
script='echo "arg 1 is: $1"'
/bin/sh -c "$script" -- "$myvar"
▁toment에 할당할 때 하는 것에 하십시오.script즉, 그것은 문자 그대로, 가변적 확장이나 다른 형태의 해석 없이 받아들여진다는 것을 의미합니다.
그repo명령어는 어떤 종류의 따옴표를 받든 상관하지 않습니다.매개 변수 확장이 필요한 경우 큰따옴표를 사용합니다.만약 여러분이 많은 것들을 후퇴시켜야 한다는 것을 의미한다면, 대부분의 것들에 대해 단일 따옴표를 사용해야 하고, 그 다음 확장이 필요한 부분에 대해서는 그것들에서 벗어나 복식으로 들어가야 한다는 것입니다.
repo forall -c 'literal stuff goes here; '"stuff with $parameters here"' more literal stuff'
당신이 관심이 있다면, 설명은 다음과 같습니다.
셸에서 명령을 실행할 때 해당 명령이 인수로 수신하는 것은 null-terminated 문자열 배열입니다.이러한 문자열에는 null이 아닌 모든 문자가 포함될 수 있습니다.
그러나 셸이 명령줄에서 문자열 배열을 구성할 때 일부 문자를 특수하게 해석합니다. 이는 명령을 입력하기 쉽게(실제로 가능하게) 설계되었습니다.예를 들어, 공백은 일반적으로 배열에서 문자열 사이의 경계를 나타냅니다. 이러한 이유로 개별 인수를 "단어"라고 부르기도 합니다.하지만 논쟁은 그 안에 공백이 있을 수 있습니다. 여러분은 단지 여러분이 원하는 것이 무엇인지를 껍데기에 말할 수 있는 어떤 방법이 필요합니다.
공백이나 다른 백슬래시를 포함한 모든 문자 앞에 백슬래시를 사용하여 셸에 해당 문자를 문자 그대로 처리하도록 지시할 수 있습니다.하지만 다음과 같은 작업을 수행할 수 있습니다.
reply=\”That\'ll\ be\ \$4.96,\ please,\"\ said\ the\ cashier
...지루해질 수 있습니다.그래서 껍질은 다른 대안을 제시합니다. 따옴표입니다.이것들은 크게 두 가지 종류가 있습니다.
이중 따옴표를 "그룹 따옴표"라고 합니다.와일드카드 및 별칭을 확장할 수 없도록 하지만 대부분 단어에 공백을 포함하기 위한 것입니다. 밖에 확장과 a가 변 수 명 및 확 장 과 같 은 기 타 사 항 종 류 보 는 내 매 를 신 호 개 령 a 가 ▁( ▁expansion ▁by the ) ▁a ▁signaled ▁command ▁of ▁other ▁and ▁parameter ▁thing▁sorts 류 ▁like 매 개$ 발생합니다. 여전히 발생합니다.물론 이중 따옴표 안에 문자 그대로의 이중 따옴표를 삽입하려면 이를 역슬래시해야 합니다.
reply="\"That'll be \$4.96, please,\" said the cashier"
단일 따옴표가 더 엄격합니다.그들 사이의 모든 것은 백슬래시를 포함하여 완전히 문자 그대로 받아들여집니다.단일 따옴표 안에 문자 그대로의 단일 따옴표를 가져올 수 있는 방법은 절대 없습니다.
다행히도 셸의 따옴표는 단어 구분 기호가 아닙니다. 그 자체로 단어를 종료하지 않습니다.동일한 단어 내에서 다른 유형의 따옴표를 포함하여 따옴표를 입력하거나 삭제하여 원하는 결과를 얻을 수 있습니다.
reply='"That'\''ll be $4.96, please," said the cashier'
따라서 백슬래시 수가 훨씬 적지만, 클로즈-싱글따옴표, 백슬래시- 리터럴-싱글따옴표, 오픈-싱글따옴표 시퀀스는 익숙해지는 데 다소 시간이 걸립니다.
현대의 셸은 POSIX 표준에서 지정하지 않은 또 다른 인용 스타일을 추가했으며, 여기서 선행 단일 인용 부호는 달러 기호로 접두사가 붙습니다.의 C 언어의 한 규약을 "및 "ANSI 문자열"이라고도.$'...'쌍 "ANSI 따옴표".이러한 문자열 내에서 백슬래시가 문자 그대로 사용되는 것에 대한 위의 조언은 더 이상 적용되지 않습니다.대신에, 그들은 다시 특별해집니다 - 백슬래시를 추가하여 문자 그대로의 단일 따옴표나 백슬래시를 포함할 수 있을 뿐만 아니라 셸은 ANSIC 문자 이스케이프를 확장합니다.\n새로운 라인을 위해,\t탭의 경우, 그리고\xHH 코드를 가진 에는 다음과 같이 입력합니다.HH하지만 그렇지 않으면 단일 따옴표로 묶인 문자열로 동작합니다. 매개 변수나 명령 대체는 수행되지 않습니다.
reply=$'"That\'ll be $4.96, please," said the cashier'
은 해야할중점은단일문자다것저다음입니장는다된에이열주에 되는 단일 입니다.reply변수는 이러한 모든 예제에서 정확하게 동일합니다.마찬가지로 셸이 명령줄을 구문 분석한 후에는 실행 중인 명령을 사용하여 각 인수 문자열이 실제로 어떻게 입력되었는지 또는 입력되었는지 정확히 알 수 없습니다.
다음은 저에게 효과가 있었던 것입니다.
QUOTE="'"
hive -e "alter table TBL_NAME set location $QUOTE$TBL_HDFS_DIR_PATH$QUOTE"
편집: (해당 의견에 따름:)
저는 그 이후로 이것을 조사해 왔습니다.저는 운이 좋게도 다시 놀고 있었습니다.하지만 명령어를 강제로 따옴표 하나로 묶어야 하는지는 잘 모르겠습니다.repo 구문을 알아봤는데 그럴 필요는 없을 것 같습니다.명령 주위에 큰따옴표를 사용한 다음 이중따옴표를 사용하지 않을 경우 내부에 필요한 단일따옴표와 큰따옴표를 사용할 수 있습니다.
그냥 printf를 사용하세요.
대신에
repo forall -c '....$variable'
printf를 사용하여 변수 토큰을 확장 변수로 바꿉니다.
예:
template='.... %s'
repo forall -c $(printf "${template}" "${variable}")
변수에는 작은 따옴표가 포함될 수 있습니다.
myvar=\'....$variable\'
repo forall -c $myvar
나는 왜 ssh 세션에서 인쇄할 나의 어색한 진술을 절대 얻을 수 없는지 궁금해서 이 포럼을 찾았습니다.여기서 직접적으로 도움이 된 것은 없지만 아래와 유사한 문제가 있는 사람이 있다면 찬성표를 주십시오.어떤 종류의 단일 또는 이중 따옴표도 도움이 되지 않는 것처럼 보이지만, 저는 모든 것을 시도하지 않았습니다.
check_var="df -h / | awk 'FNR==2{print $3}'"
getckvar=$(ssh user@host "$check_var")
echo $getckvar
무엇을 얻었습니까?아무것도 없는 짐.
수정: 이스케이프\$3사용자의 인쇄 기능에서.
이것이 당신에게 효과가 있습니까?
eval repo forall -c '....$variable'
언급URL : https://stackoverflow.com/questions/13799789/expansion-of-variables-inside-single-quotes-in-a-command-in-bash
'codememo' 카테고리의 다른 글
| Bash에서 $PATH 변수에서 경로를 제거하는 가장 우아한 방법은 무엇입니까? (0) | 2023.05.18 |
|---|---|
| VBA를 사용하여 Excel의 조건부 서식에서 배경색을 가져오는 방법 (0) | 2023.05.18 |
| 사용자 변수와 시스템 변수의 차이점은 무엇입니까? (0) | 2023.05.18 |
| 파일 이름 없이 md5sum을 사용하여 해시 값만 가져옵니다. (0) | 2023.05.18 |
| SQL Server 연결을 프로그래밍 방식으로 테스트하는 가장 좋은 방법은 무엇입니까? (0) | 2023.05.18 |