쉘 스크립트에서 명령이 제대로 작동하지 않습니다.

쉘 스크립트에서 명령이 제대로 작동하지 않습니다.

출력은 다음과 같습니다.

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null 
야쉬 샤
핵심 조각
CoreFragment_5G
핵심 조각
델리안
야쉬 샤
콘패스트
앱버즈_기술
공생
20096641
CoreFragment_5G
황색_AP1
레드윙랩스_5G

스크립트에 작성된 동일한 내용이 동일한 방식으로 작동하지는 않습니다.

다음은 위 명령을 사용하는 스니펫입니다.

for ssid_name in $(sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null)
do
    echo "$ssid_name"
done

나는 다음과 같은 결과를 얻습니다.

야쉬
핵심 조각
CoreFragment_5G
핵심 조각
야쉬
붉은 날개
실혐실
콘패스트
앱버즈_기술
공생
CoreFragment_5G
붉은 날개
LABS_5G

노트: 출력에 공백이 있으면 새 줄로 처리됩니다.

우분투 18.04를 사용하고 있습니다.

답변1

먼저 그렇지 않다는 점에 유의하세요.하나명령은 다르게 동작합니다. 코드 조각에서 표준 출력은 완전히 다른 두 가지 명령으로 작성됩니다.
첫 번째 인쇄물 의 출력 sed과 두 번째 인쇄물의 출력은 다음과 같습니다.

  1. 의 출력이 sed대체됩니다(명령 대체를 통해 $(...)) in.
  2. 결과 문자열은 요소 목록으로 확장됩니다.
  3. 각 항목은 차례로 에 할당 ssid_name되고 인쇄됩니다 echo.

포인트 2의 확장은 내부 필드 구분 기호( ) 값을 기반으로 하며 IFS기본값은 입니다 <space><tab><newline>. 그러므로,귀하의 솔루션for이는 교체된 문자열을 줄바꿈으로 분할하는 것만 허용하기 때문에 작동합니다 .

귀하의 답변과는 별도로 많은 쉘이 해당 구문 ( )을 지원 $'\n'하더라도 이식성이 없다는 점에 유의하십시오. 그러나 다음과 같은 할당을 사용할 수 있습니다.$'string'

IFS='
'

입력 행을 처리하는 또 다른 구성은 read이를 루프에서 사용하는 것입니다 while.

sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null |
while IFS= read -r i; do
    printf '%s\n' "$i"
done

여기서 sed출력의 각 행은 값 IFS(이 경우 단어 분할 효과를 방지하기 위해 빈 문자열로 설정됨)을 기준으로 분할되지만 행은 로 read구분된 상태로 유지됩니다 IFS.

답변2

루프 대신 while루프를 사용하는 것이 좋습니다 .readfor

sudo iwlist scan 2>/dev/null |grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null | while IFS= read -r ssid_name
do
    echo $ssid_name
done

당신은 또한 볼 수 있습니다https://mywiki.wooledge.org/BashFAQ/001

답변3

for 루프 앞에 다음 줄을 코드에 추가하면 내 경우에는 제대로 작동했습니다.

IFS=$'\n'

관련 정보