내가 원하는 코드 조각은 다음과 같습니다.
루프를 5번 반복합니다.
파일에서 한 줄을 가져옵니다(각 반복마다 다음 줄을 가져와야 합니다).
해당 행을 파일 제목으로 사용하십시오.
시작 부분에 타임스탬프를 넣습니다.
ping에 대한 인수로 해당 행을 사용하십시오. 사용자에게 코드 진행 상황을 알리는 문장을 인쇄합니다.
반복은 이미 작동합니다.
sed 부분을 건너뛰면 모든 것이 작동하지만 동일한 대상에 대해 ping을 5번 실행합니다.
호스트.txt 파일의 각 줄에는 핑하려는 단일 IP 주소가 있습니다.
for ((i>=1;i<=5;i++))
do
sed -n "$i p" hosts.txt | read output
touch "$output.txt"
date >> "$output.txt"
printf "\nComeçando o teste de $output."
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done
문제는 sed 구문에 대해 뭔가 잘못하고 있다는 것입니다. bash를 직접 시도하면 sed -n 1p hosts
첫 번째 줄이 표시됩니다. 하지만 그 숫자가 $i가 되어야 하기 때문에 p 바로 앞에 $i를 넣으면 bash는 변수 i와 그 뒤에 인수 p를 더하는 대신 ip를 변수로 해석합니다.
이 동작을 수정하고 다시는 문제를 일으키지 않으려면 어떻게 해야 합니까?
답변1
나는 당신이 bash를 사용하고 있다고 가정하므로 이것이 더 잘 작동할 것입니다:
for ((i=1;i<=5;i++))
do
sed -n "$i p" hosts.txt | (
read output
touch "$output.txt"
date >> "$output.txt"
printf "\nComeçando o teste de $output."
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
)
done
당신이 겪고 있는 문제는 bash
외부의 대부분의 쉘 해석기가 ksh
모든 파이프라인 구성 요소를 하위 쉘에 배치하므로 output
변수가 설정된 후 즉시 손실된다는 것입니다.
for
또한 변수가 초기화되지 않았기 때문에 정의되지 않은 동작이 발생한 루프를 수정했습니다 i
.
답변2
문제는 관찰한 대로 i
및 둘 다 ip
유효한 변수 이름이라는 것입니다. 따라서 $i
바로 뒤에 문자가 오는 값을 사용하려면 p
유연한 중괄호를 사용하여 변수 이름이 시작하고 끝나는 위치를 명확하게 구분할 수 있습니다.
sed -n "${i}p" hosts.txt | read output
답변3
조금 더 간단한 해결책은 다음과 같습니다.
for ((i=1; i<=5; i++))
do
read output
date >> "$output.txt"
printf "\nComeçando o teste de %s." "$output"
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt
< hosts.txt
마지막 줄 끝의 에 주목하세요 done
. 이것은 hosts.txt
한 번 열리고 처음 5줄만 읽습니다. don_crissti가 언급했듯이 루프를 수행한다는 것은 파일을 5번 sed … hosts.txt | read output
읽는다는 의미입니다 . hosts.txt
이 read output
루프의 나머지 부분(파이프라인이 아님)과 평행하므로 루프의 나머지 코드는 output
파일에서 읽은 값에 액세스할 수 있습니다. 또한 (지정한 것처럼) 필요하지 않습니다 touch
. 만들 것이다command >> file
file
이미 존재하지 않는 경우.
파일 중 하나가 이미 존재하는 경우 hostname.txt
이 코드는 해당 파일에 새 정보를 추가합니다. 오래된 데이터를 버리고 처음부터 시작하려면 date > "$output.txt"
대신 을 수행하십시오 date >> "$output.txt"
.
알 수 없는 데이터를 에 직접 전달하지 않도록 주의하세요 printf
. "호스트 이름" 중 하나에 이 포함된 (가능성이 낮습니까?) 이벤트가 발생하면 %
코드에서 해당 이름이 왜곡됩니다. %s
(문자열을 인쇄하기 위해) 외부 데이터를 전달하는 것이 더 좋습니다 .
파일 의 처음 다섯 줄만 읽고 중지할지, 아니면 전체 파일을 읽을지 여부를 말하지 않고 hosts.txt
우연히 그 길이가 다섯 줄이라는 것을 알게 됩니다. 전체 파일을 읽으려면 다음을 수행하십시오.
while read output
do
date >> "$output.txt"
printf "\nComeçando o teste de %s." "$output"
printf "\nTeste em andamento."
ping -c 10 -i 1 "$output" >> "$output.txt"
done < hosts.txt
파일 끝에 도달하면 명령문이 read output
실패하고 루프가 종료됩니다.