변수를 bash 스크립트에 매개 변수로 전달하고 bash 스크립트에서 평가하도록 하는 방법이 있습니까?
주어진:
# cat /path/to/file/of/host/names
bob
tom
joe
etc...
# dofor
FILE=$1
shift
CMD=$*
while read host; do
# recursively turns "ssh \$host hostname" from $@ into:
# ssh bob hostname
# ssh tom hostname
# ssh joe hostname
# etc...
eval $CMD
done < $FILE
언제:
# dofor /path/to/file/of/host/names "ssh \$host hostname"
그 다음에ssh host hostname
: /path/to/file/of/host/names에 나열된 각 호스트 이름에 대해 실행 결과를 받습니다. 예를 들어:
bob.example.com
tom.example.com
joe.example.com
etc...
답변1
이 시도:
#!/bin/bash
FILE=$1
shift
CMD=$*
cmds=""
source <({
cat $FILE | while read host; do
echo $CMD | sed -e "s|\$host|$host|g"
done
})
답변2
당신은 그것을 사용할 수 있습니다
#!/bin/bash
FILE=$1
exec 3<$FILE
while read -u 3 host; do
$2 $host $3
done
따라서 다음과 같은 경우:
$ cat /tmp/hostnames
some.host1.com
another.host2.net
some.host3.org
some.host4.com
그런 다음 실행하면 dofor.sh /tmp/hostnames ssh ls
순서대로 실행됩니다.
ssh some.host1.com ls
ssh another.host2.net ls
ssh some.host3.org ls
ssh some.host4.com ls
편집 1:
더 긴 명령(또는 그 일부)을 변경하려면 따옴표를 사용 ssh
하세요 .ls
dofor.sh /tmp/hostnames "ssh -p 23" "ls -lh /"
편집 2:
다음 스크립트를 사용하면 $host
명령의 어느 위치에서나 변수를 사용할 수 있습니다.
#!/bin/bash
exec 3<$1
while read -u 3 host; do
eval $2
done
(저는 이것을 단축했습니다 - 쓸모없는 $FILE
변수는 도입하지 않았습니다.) 여기서 중요한 부분은아포스트로피$host 변수를 포함하는 명령 주변:
dofor.sh /tmp/hostnames 'echo "trying $host :"; ssh -p 23 myuser@$host "ls -lh /"'
하지만경계하다사용하는 것은 위험합니다 eval
(참조l0b0의 벽) 파일의 /tmp/hostnames
특정 줄에 명령이 포함되어 있으면 해당 명령이 실행되기 때문입니다.로 사용하지 않는 것이 좋습니다 root
!
답변3
이것은 효과가 있지만진짜콘텐츠를 완전히 제어할 수 없다면 나쁜 생각입니다.$FILE
그리고여기에는 매우 간단한 진술만 포함되어 있습니다.
while read -r
do
$REPLY
done < $FILE
SSH 예의 경우 호스트 이름을 반복하여 더 간단한 작업을 수행할 수 있습니다.
while read -r host
do
echo -n "${host}:"
ssh "$host" hostname
done 9< "$FILE"
my hostname:remote hostname
항목 목록 이 반환되어야 합니다 .
실제 명령이 포함된 파일이 있는 경우 공백이 올바르게 처리되는지 확인해야 합니다. 그것을 처리할 수 있는 유일한 방법은어느매개변수(예를 들어 echo
매개변수가 여러 줄인 명령 포함)는 사용자 정의 형식을 사용합니다. 비교적 간단한 접근 방식은 각 명령과 인수를 ␀ 문자로 구분하고 명령의 마지막 인수와 다음 명령 사이에 추가 ␀ 문자를 배치하는 것입니다.