작은따옴표나 큰따옴표 안에 변수를 확장하는 방법

작은따옴표나 큰따옴표 안에 변수를 확장하는 방법

2개의 시스템이 있고 동일한 디렉토리 구조를 가지고 있습니다. 로컬 시스템에서 여러 명령을 실행하고 원격 시스템에서도 동일한 명령을 실행하고 싶습니다.

와일드카드를 사용하므로 패키지의 새 버전이 있을 때 bash 스크립트를 다시 편집할 필요가 없습니다!

내 bash 스크립트에는 다음 줄이 있습니다.

varWheelsDir="/tmp/wheels"
set -x
# Install local
pip3 install --force-reinstall --user "${varWheelsDir}/bbw"*
# Install remote
ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw$*'"

이것도 확장됨

+ pip3 install --user /tmp/wheels/bbw-2.10.0-py3-none-any.whl
+ ssh -t admin@otherhost 'pip3 install --user '\''/tmp/wheels/bbw'\'''

분명히 SSH 라인의 확장이 작동하지 않습니다.

어떻게 입력하는지 알아요ssh -t

답변1

분명히 SSH 라인의 확장이 작동하지 않습니다.

해당 진술의 문법적 문제를 제쳐두고, 확장이 예상한 대로 작동하지 않는다는 점을 제외하면 확장이 "작동하지 않는다"는 것이 분명하지 않습니다. 확장 방법과 기대하는 내용을 포함하면 도움이 될 것입니다.

SSH 클라이언트가 아닌 원격 호스트에서 확장이 이루어지기를 원한다는 뜻인 것 같습니다. 이 경우 로컬 셸에 전달된 인수를 이스케이프하지만 원격 확장을 허용하려면 인용도 변경해야 합니다.

ssh -t admin@otherhost "pip3 install --user \"\${varWheelsDir}/bbw\*\""

답변2

ssh 명령이 "build"될 때 어떤 부분이 확장되는지, 결과는 무엇인지, 원격 호스트에서 명령을 실행하면 어떤 부분이 확장되는지 확인해야 합니다.

첫 번째 시도

ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw$*'"
# expands to
ssh -t admin@otherhost "pip3 install --user '/tmp/wheels/bbw'"
# and executes on the other host
pip3 install --user '/tmp/wheels/bbw'

$*여기에서는 사용할 수 없는 위치 매개변수로 확장됩니다. 바라보다https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#index-_002a

당신이 그렇게한다면

ssh -t admin@otherhost "pip3 install --user '${varWheelsDir}/bbw'*"
# it should expand to
ssh -t admin@otherhost "pip3 install --user '/tmp/wheels/bbw'*"
# which executes on the other host
pip3 install --user '/tmp/wheels/bbw'*

( *로컬 호스트에서 글로빙을 방지하기 위해 큰따옴표 안에 있지만 원격 호스트에서 파일 글로빙을 허용하려면 작은따옴표 밖에 있습니다.)

피곤해요

x=/tmp
ssh -t otherhost "ls -l '$x/'*"

나를 위해 일하고 원격 호스트의 임시 디렉토리를 모두 나열했습니다.

답변3

많은 시스템에는 다음을 수행할 수 있는 구성이 AcceptEnv LC_*있습니다 .sshd

export LC_DIR="$varWheelsDir"
shell_code='
  pip3 install --force-reinstall --user "$LC_DIR"/bbw*
'
eval "$shell_code" # interpreted by current shell

ssh -e SendEnv=LC_DIR -t admin@otherhost "$shell_code"
  # interpreted by the login shell of admin on otherhost,
  # assuming it is Bourne-like

동일한 셸 코드를 사용하여 로컬 및 원격으로 실행하고 $LC_DIR동일한 내용으로 변수를 공유합니다.

또는 로컬 셸이 zsh이고 on의 로그인 셸이 Bourne과 유사하다는 것을 알고 있는 경우 admin안전한 방법으로 otherhost로컬 변수의 내용을 포함하고 참조하는 셸 코드를 구성할 수 있습니다.$varWheelsDir

pip3 install --force-reinstall --user "${varWheelsDir}"/bbw* # local
ssh -t admin@otherhost "
  pip3 install --force-reinstall --user ${(qq)varWheelsDir}/bbw"* # remote

${(qq)var}여기서 작은따옴표를 사용하여 sh 구문의 내용을 인용합니다 ($var임의의 데이터를 참조하는 가장 안전한 형태).

최신 버전에는 확장된 따옴표 연산자가 bash있지만 어떤 경우에는 이식할 수 없는 bash 관련 구문을 생성하고 작은 따옴표 이상을 사용하므로 on의 로그인 셸이 발생하는 경우에만 작동합니다 (바람직하게는 동일한 버전에서 실행 중). 동일한 로캘).${var@Q}$varadminotherhostbash

admin귀하의 로그인 셸이 otherhostBourne의 셸과 유사하다고 보장할 수 없는 경우 다음을 참조하세요.원격 사용자의 로그인 셸을 모르고 SSH를 통해 임의의 간단한 명령을 어떻게 실행할 수 있습니까?가능한 방법.

관련 정보