SSH 세션에서 파이프를 사용한 읽기가 실패하는 이유는 무엇입니까?

SSH 세션에서 파이프를 사용한 읽기가 실패하는 이유는 무엇입니까?

find로 찾은 폴더 대신 빈 줄이 표시되는 이유는 무엇입니까?

ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null \
  -o batchmode=yes -o passwordauthentication=no [email protected] \
  "sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info \
    | while read linea; do echo $linea; done";

답변1

Romeo가 지적했듯이 명령 주위에 큰따옴표를 사용합니다. 이는 명령을 실행하기 전에 변수가 확장된다는 의미입니다 ssh. 따라서 while 루프의 본문은 다음과 같습니다.

echo $linea

이전에는 존재하지 않았을 수 있으므로 ssh linea전달된 명령은 빈 문자열로 echo대체 됩니다.linea

명령 매개변수 주위에 작은따옴표를 사용하면 매개변수 확장이 발생하지 않고 문자열이 그대로 전달되므로 괜찮습니다.

ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null -o batchmode=yes -o passwordauthentication=no [email protected] 'sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info | while read linea; do echo $linea; done'

또는 탈출하면 $쉘이 확장하지 않도록 지시합니다.

답변2

큰따옴표를 사용하고 있기 때문입니다. 이는 $linea실행되기 전에 확장되었음을 의미합니다. ssh다음을 사용하여 이를 테스트할 수 있습니다 set -x.

$ set -x
$ ssh user@host "find /var  | while read line; do echo $line; done"
+ ssh user@host 'find /var  | while read line; do echo ; done'

보시다시피 실제 실행되는 명령에는 echo변수가 없습니다. 이를 방지하려면 큰따옴표 대신 작은따옴표를 사용할 수 있습니다.

ssh user@host 'find /var  | while read line; do echo "$line"; done'

또는 로컬에서 while 루프를 실행합니다.

ssh user@host find /var  | while read line; do echo "$line"; done

위의 예에서는 명령의 출력에 따라 find원격 호스트에서 실행되고 로컬로 실행됩니다 .whilessh

답변3

루프를 피하세요 while read.

ssh [email protected] '
  sudo find "/folder/CFGKCP/KCS Pro/Job Setup" -name JOBCFG.info -exec sed -i "
    /^\[General]/,/^\[/ {
      s/^JobRoot = .*/JobRoot = C:\\\\LOTES\\\\TMP\\\\\r/
    }" {} +'

또는 작은따옴표를 사용하세요.

ssh [email protected] '
  sudo find "/folder/CFGKCP/KCS Pro/Job Setup" -name JOBCFG.info -exec sed -i '\''
    /^\[General]/,/^\[/ {
      s/^JobRoot = .*/JobRoot = C:\\LOTES\\TMP\\\r/
    }'\'' {} +'

(이것은 \r이미 GNU에만 해당되므로 이를 사용할 수도 있습니다 -i.)

답변4

변수를 따옴표로 확장하는 방법에 대해 설명해 주셔서 감사합니다. 이제 문제가 시작되는 위치를 이해했습니다. 에코 대신 순서를 사용하기 때문에 중첩된 작은 따옴표를 사용해야 합니다. 더 자세한 예는 다음과 같습니다.

ssh [email protected] '
    sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info|
        while read line; do
            sudo sed '/^\[General\]/,/^\[/ {s/^JobRoot = .*/JobRoot = C:\\LOTES\\TMP\\\r/}' "$line" |sudo tee "$line".modificado; sudo mv -f "$line".modificado "$line";
        done
';

관련 정보