저는 여러 기능을 갖춘 스크립트를 작업해 왔습니다.
"적절한 콘텐츠 없음" 줄을 표시하지 않고 "/usr/share/applications" 폴더에 있는 모든 응용 프로그램에 대한 Whatis 명령의 출력을 표시하는 기능을 추가하려고 합니다.
내 현재 명령 시도는 다음과 같습니다
whatis $(ls /usr/share/applications | cut -d "." -f 1) | grep -i -v "nothing appropriate"
내가 겪고 있는 문제는 grep 명령이 작동하지 않는 것 같아서 "적합하지 않음"이라는 문구가 포함된 줄이 계속 표시된다는 것입니다.
또한 "replace" 및 "sed" 명령을 사용하여 원하지 않는 줄을 공백으로 변환하는 등 다양한 대안을 시도했지만 이 역시 문제를 해결하지 못했습니다.
위의 모든 시도에서는 명령을 직접 출력해 보았고 출력을 파일로 라우팅하고 파일의 "cat" 출력에 대해 필터를 수행해 보았습니다.
누구든지 다른 옵션을 추천할 수 있나요?
답변1
오류 메시지는 일반적으로 에 기록되며 으로 stderr
파이프하면 됩니다 . Bourne과 같은 쉘에서 stdout 및 stderr을 파이프하려면 다음을 수행할 수 있습니다.stdout
grep
fish
whatis... 2>&1 | grep -v 'nothing appropriate'
이는 stdout과 stderr이 결국 stdout에 병합된다는 것을 의미합니다.
거기에 있는 쉘은 파이프를 보고 이를 whatis... 2>&1
합계 로 분할 grep -v 'nothing appropriate'
하고 파이프의 쓰기 끝인 왼쪽 파이프의 stdout(파일 설명자 1)과 다른 파이프의 오른쪽 파이프의 stdin(fd 0)을 사용하여 이를 감지합니다. 파이프는 각각 별도의 프로세스에서 동시에 실행됩니다.
양쪽에서 리디렉션이 처리됩니다. 2>&1
말: fd 2를 fd 1에서 열었던 동일한 콘텐츠(여기서는 파이프)로 리디렉션합니다. 따라서 fd 1과 2는 모두 파이프로 들어갑니다.
rc 유사 쉘에 해당하는 구문은 whatis... >[2=1] | grep...
및 csh
-like 쉘 과 같습니다 whatis... |& grep...
(zsh에도 적용됨).
ksh93
, zsh
또는 를 사용하면 필터링된 파이프라인에만 보낼 bash
수도 있습니다 .stderr
whatis... 2> >(grep -v 'nothing appropriate' >&2)
그러나 grep
명령은 기다리지 않으므로 명령이 반환된 후 추가 오류 메시지가 표시될 수 있습니다. 이는 다음을 통해 피할 수 있습니다 zsh
.
{whatis...} 2> >(grep -v 'nothing appropriate' >&2)
(또는더 괴로운 ksh93
건bash
).
당신 은 yash
사용할 수 있습니다프로세스 리디렉션(구문은 다음과 유사합니다.프로세스 교체, 그러나 차이점은 확장이 아닌 리디렉션 연산자라는 것입니다. 동일한 문제는 필터 명령을 기다리지 않는다는 것입니다.
whatis... 2>(grep -v 'nothing appropriate' >&2)
대신 에 로 cut -d "." -f 1
변경하게 됩니다 . 분할+글로브를 호출하므로 또는 글로브 문자를 포함하는 애플리케이션 이름에도 문제가 있습니다.org.gnome.Settings.desktop
org
org.gnome.Settings
$IFS
이를 통해 zsh
다음을 수행할 수 있습니다.
whatis -- /usr/share/applications/*.desktop(:t:r) |& grep -v 'nothing appropriate'
여기서 파일의 ail(dirname)과 루트 이름(확장자 없음)을 :t
취하고 is .t
:r
|&
2>&1 |
에서는 bash
다음을 수행할 수 있습니다.
(
shopt -s failglob
set /usr/share/applications/*.desktop
set -- "${@##*/}"
whatis -- "${@%.*}" 2>&1
) | grep -v 'nothing appropriate'
는 "${@##*/}"
와 동일하며 :t
, "${@%.*}"
는 와 동일합니다 :r
.
GNU ls
9.0 이상에서는 다음을 수행할 수도 있습니다.
ls --zero /usr/share/applications/ |
LC_ALL=C sed -zn 's/\.desktop$//p' |
xargs -r0 whatis -- 2>&1 |
grep -v 'nothing appropriate'
ls --zero
사후 처리 가능한 형식으로 목록을 출력하고, 확장자 를 sed
제거하고 , 대체 항목이 있는 경우( 확장자가 없는 파일은 .desktop
제외) 결과를 출력 하고 , 목록을 에 전달하고 오류를 필터링합니다 ..desktop
xargs
whatis
grep
nothing appropriate
GNU를 사용하면 basename
다음도 수행할 수 있습니다.
(
shopt -s failglob
basename -zs .desktop /usr/share/applications/*.desktop
) |
xargs -r0 whatis -- 2>&1 |
grep -v 'nothing appropriate'
또한 데스크탑 파일의 이름은 실행 파일의 이름(있는 경우)과 일치하지 않는 경우가 많으므로 해당 매뉴얼 페이지가 없을 수도 있습니다.
whatis
.desktop
루트 이름을 에 전달하는 대신 이러한 파일에서 일부 필드를 추출할 수도 있습니다 . 예를 들어:
(cd /usr/share/applications &&
grep -HPom1 -e '^GenericName=\K.*' -- *.desktop
)
GenericName
이러한 파일에서 필드가 처음으로 나타나는 값이 추출됩니다.