SSH를 사용하여 다양한 서버에서 일부 데이터를 캡처하고 특정 조건에서 일부 명령을 실행하고 싶습니다.
나는하고 싶지 않다 :
if ssh $host test -f /file; then
# If file exists
var=$(ssh $host long pipeline)
else
# if it doesn't
var=$(ssh $host another long pipeline)
fi
왜냐하면 프로세스가 더 길어지기 때문입니다. 원격 컴퓨터에서 if else 작업을 수행하고 싶습니다.
여러 가지 방법을 시도했지만 성공하지 못했습니다.
var=$(ssh $host if [ -f /file ]\; then long pipeline1 \; else long pipeline2 \; fi)
기반답변, 작동하지만 파이프라인1의 마지막 명령은 해당 명령 else
과 파이프라인2의 나머지 부분을 인수로 가정합니다.
command: can't read else: No such file or directory
...
command: can't read fi: No such file or directory
그런 다음 이것을 시도했습니다.
var=$(ssh $host test -f /file \&\& pipeline1 \|\| pipeline2)
마찬가지로,pipeline1의 마지막 명령은 ||
해당 인수로 간주됩니다.
나는 또한 아래에서 시도했습니다 (이것),달리기:
do_this () {
if [ -f /file ]; then
pipeline1
else
pipeline2
fi
}
var=$(ssh $host "$(set); do_this")
그러나 내 변수에 영향을 주지 않지만 내 스크립트에는 보기 흉한 원치 않는 오류 메시지를 인쇄합니다.
bash: line 1: BASHOPTS: readonly variable
bash: line 8: BASH_VERSINFO: readonly variable
bash: line 24: EUID: readonly variable
bash: line 71: PPID: readonly variable
bash: line 82: SHELLOPTS: readonly variable
bash: line 92: UID: readonly variable
어떤 제안이 있으십니까?
고쳐 쓰다
내 파이프라인이 무엇인지 포함해야 한다고 생각합니다. 기본적으로 그것은 단지 텍스트 처리 묶음일 뿐입니다.
cat file | grep "something" | sed 's/.*="\(.*\)"/\1/' | tr ' ' '-'
의 답변을 바탕으로Jechisel, 즉, 명령을 작은따옴표로 묶어야 합니다.
var=$(ssh $host 'if [ -f /file ]; then cat file | grep "something" | sed 's/.*="\(.*\)"/\1/' | tr ' ' '-' ; else cat otherfile | ... ; fi'
나는 가지고있다 tr: invalid option -- ';'
. 매개변수 tr
로 사용됩니다 .;
작동 방식은 다음과 같습니다 heredoc
.
var=$(ssh $host <<-EOF
if [ -f file ]; then
pipeline1
else
pipeline2
fi
EOF
)
그러나 sed에서 사용하는 정규식으로 인해 vim의 색상이 손상됩니다. heredoc
지금은 이 답변을 받아들이겠습니다 .
업데이트 2:내 질문이 중복되지 않은 것 같습니다.sshpass의 여러 명령, 내 상황은 더 구체적이었고 다른 스레드는 일반적으로 물었습니다.
답변1
존재하다:
ssh host code
ssh
실제로 인수로 전달한 코드를 해석하기 위해 쉘(대상 사용자의 로그인 쉘)을 실행합니다. 여러 인수가 제공되면 ssh는 인수를 공백으로 연결하고 사용자의 로그인 쉘이 host
이를 다시 해석하도록 합니다.
일반적으로 말하면, 당신은 합격하고 싶습니다하나단일 코드 인수를 선택 ssh
하고 로컬 셸이 확장되지 않도록 작은따옴표로 묶어야 합니다.
원격 사용자의 로그인 쉘이 Bourne/POSIX와 유사하다는 것을 알고 있는 경우 수행해야 할 작업은 다음과 같습니다.
var=$(ssh "$host" '
if [ -f /file ]; then
pipeline1
else
pipeline2
fi'
)
원격으로 해석할 코드에 작은따옴표가 포함되어야 하는 경우 이를 삽입해야 합니다 '\''
(작은따옴표 유지, 인용된(백슬래시 사용) 작은따옴표 삽입, 작은따옴표 다시 입력).
원격 사용자의 셸을 보호하지 않고 표준 입력을 통해 원격 명령에 데이터를 전달할 필요가 없는 경우(그리고 SSH 연결 이외의 다른 것으로 리디렉션되지 않는 한 원격 명령이 표준 입력에서 읽지 않음) 다음을 수행할 수 있습니다.
ssh "$host" sh << 'EOF'
if [ -f /file ]; then
pipeline1
else
pipeline2
fi
EOF
첫 번째 항목을 참조하여 EOF
이 문서에서 로컬 셸이 확장되지 않도록 합니다. sh
우리는 스크립트를 작성하는 데 사용할 구문을 알 수 있도록 표준 입력의 코드를 해석하기 위해 명시적인 호출을 수행합니다 .
이 접근 방식을 사용하면 작은따옴표를 이스케이프 처리할 필요도 없습니다.
당신의
cat file | grep "something" | sed 's/.*="\(.*\)"/\1/' | tr ' ' '-'
다음과 같이 쓸 수 있습니다:
<file sed '/something/!d; s/.*="\(.*\)"/\1/; y/ /-/'
그래서 이것은 우리에게 다음을 제공합니다:
ssh "$host" '
file=/path/to/some/file
otherfile=/path/to/some/other/file
if [ -f "$file" ]; then
<"$file" sed '\''/something/!d; s/.*="\(.*\)"/\1/; y/ /-/'\''
else
<"$otherfile" ...
fi'
(원격 사용자의 로그인 셸이 Bourne/POSIX 유사 구문과 구문이 다른 csh, tcsh, fish, rc, es, akanga인 경우 이 명령은 작동하지 않습니다.)
또는:
ssh "$host" sh << 'EOF'
file=/path/to/some/file
otherfile=/path/to/some/other/file
if [ -f "$file" ]; then
<"$file" sed '/something/!d; s/.*="\(.*\)"/\1/; y/ /-/'
else
<"$otherfile" ...
fi
EOF
답변2
몇 년 전에도 비슷한 일을 했는데, 이렇게 했습니다.
먼저 종료 상태를 테스트하세요.
ssh -t remoteuser@lremotehost 'if [[ -e /etc/fstabs ]]; then exit 0; else exit 127; fi' >/dev/null 2>&1
종료 상태를 확인하세요.
echo $?
출력 127
은 없기 /etc/fstabs
때문에/etc/fstab
이제 후행이 없음을 확인 /etc/fstabs
하도록 변경합니다./etc/fstab
s
ssh -t remoteuser@lremotehost 'if [[ -e /etc/fstab ]]; then exit 0; else exit 127; fi' >/dev/null 2>&1
종료 상태를 다시 확인하세요.
echo $?
출력은 원격 시스템에 0
출력이 있기 때문입니다./etc/fstab
그런 다음 변수에 넣고 종료 상태를 확인하고 이를 기반으로 스크립트를 실행하면 됩니다. 또한 종료 상태를 변수에 저장하십시오.
var=$(ssh -t remoteuse@remotehost 'if [[ -e /etc/fstabs ]]; then exit 0; else exit 127; fi; exec bash -li' >/dev/null 2>&1); pid=$?
case $pid in
0) echo 'good!';;
*) echo 'bad!' >&2;;
esac
이것이 제가 이 상황에서 살아남은 방법입니다. 완벽한 해결책이라고 말할 수는 없지만 확인해 보세요. 그런데 SSH 키를 원격 호스트에 전달했기 때문에 SSH를 통해 로그인할 때 비밀번호를 확인하지 않습니다. 나는 또한 두 컴퓨터 모두에서 로그인 셸로 bash를 사용하고 있는데, 이것이 바로 내가 exec bash -li
다음과 같은 이유입니다.