IFS를 사용하여 콜론으로 구분된 경로 목록에서 루프를 읽는 동안 Bash

IFS를 사용하여 콜론으로 구분된 경로 목록에서 루프를 읽는 동안 Bash

where처럼 동작하는 bash 함수를 작성하려고 합니다 tcsh. 지정된 이름을 가진 실행 파일에 대한 tcsh모든 where내장 함수, 별칭 및 절대 경로가 PATH숨겨져 있더라도 나열됩니다.

tcsh> where tcsh
/usr/bin/tcsh
/bin/tcsh

그 일환으로 나는 그 안에 있는 모든 것을 반복해서 살펴 $PATH보고 적절한 이름을 가진 실행 파일이 있는지 확인하고 싶습니다.

$PATH다음 bash 조각은 콜론으로 구분된 경로 목록을 반복하고 각 구성 요소 뒤에 개행 문자를 인쇄하도록 설계되었지만 모든 내용의 전체 내용을 한 줄에 인쇄하는 것처럼 보입니다.

#!/bin/bash
while IFS=':' read -r line; do
    printf "%s\n" "$line"
done <<< "$PATH"

지금 상태로는 bash where그냥 ./where인쇄하세요 ./usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

그렇다면 루프 변수의 값이 콜론으로 구분된 경로 목록의 각 세그먼트가 되도록 while 루프를 설정하려면 어떻게 해야 합니까?

답변1

read읽는 줄에서 단어를 구분하는 데 사용되며, IFS그 안에 문자가 처음 나타날 때까지 읽은 내용이 전달되지 않습니다.read

IFS=: read -r a b

한 줄을 읽고 첫 번째 부분 앞에 해당 부분을 넣고 나머지 부분을 넣 습니다 :.$a$b

IFS=: read -r a

전체 줄(나머지 부분)을 넣습니다 $a(줄에 문자가 하나만 포함되어 있고 :해당 줄의 마지막 문자가 아닌 경우).

첫 번째 항목을 읽으려면 ( 또는 하나만) 을 :사용할 수 있습니다 .read -d:ksh93zshbash

printf %s "$PATH" | while IFS= read -rd: dir || [ -n "$dir" ]; do
  ...
done

(추가 개행 문자를 추가하기 위해 as를 사용하지 않습니다 <<<).

또는 표준 분사를 사용할 수 있습니다.

IFS=:; set -o noglob
for dir in $PATH""; do
  ...
done

이제 몇 가지 경고에 유의하세요.

  • $PATH구성 요소는 현재 디렉터리를 나타냅니다.
  • 비어 있음은 $PATH현재 디렉터리를 의미합니다. 즉, $PATH현재 디렉터리의 구성 요소가 포함되어 있으므로 while read -d:이 경우 반복은 오류가 됩니다.
  • //file/file일부 시스템에서는 그렇지 않기 때문에 $PATH포함 된다면 /그런 점에 주의가 필요합니다 $dir/$file.
  • 하나설정되지 않음$PATH는 다음을 의미합니다.기본검색 경로를 사용하려면 $PATH가 설정되어 있지만 비어 있는 것과 다릅니다.

tcsh이제 / zsh의 명령 과 동일하다면 ' 를 where사용할 수 있습니다 .bashtype -a

추가 자료:

답변2

텍스트를 처리하기 위해 쉘 루프를 사용하지 마십시오.

대신 awk, 또는 tr, 심지어 를 사용하세요 sed.

printf %s\\n "$PATH" | tr ':' '\n'

printf %s "$PATH" | awk 'BEGIN {RS=":"}; 1'

또는 처리 중인 쉘 변수이므로 bash패턴 대체를 사용하십시오.

echo "${PATH//:/
}"

(바라보다 LESS=+/parameter/pattern man bash.)

답변3

pure bash, 이는 다음과 관련이 있습니다.와일드카드두 번째 방법, 그러나 이것은 한 줄입니다.

echo -e "${PATH//:/"\n"}"

답변4

쉘 유틸리티:

echo $PATH | tr ':' '\n'

관련 정보