func
표 형식 출력이나 json 출력을 생성할 수 있는 함수가 있습니다 . 이 문제를 해결하는 전통적인 방법은 다음과 같은 매개변수를 사용하는 것입니다.
$ func -j | jq .firstField
$ func -t | awk '{print $1}'
나는 "미리 살펴보고" 파이프라인의 다음 단계를 기반으로 출력 유형을 추론하고 싶습니다. 이상적인 사용법은 간단합니다.
$ func | jq .firstField
$ func | awk '{print $1}'
func 어딘가에서 파이프라인의 다음 단계의 0번째 매개변수가 포함되어 있는지 확인한다고 상상합니다 j
. 그렇다면 json을 생성하고, 그렇지 않으면 테이블을 생성합니다.
Bash는 그러한 마법을 허용합니까? 그렇다면 어떻게 해야 할까요?
답변1
/proc
프로세스 도구를 통해 프로세스 트리에서 또는 존재하는 경우 유형 파일 시스템을 마이닝하여 회수할 수 있는 것 외에는 파이프라인과 연관된 공식 메타데이터나 쿼리 API가 없습니다 . 상위 셸은 (아마도) 메모리 어딘가에 완전한 파이프를 갖고 있으며 관련된 다양한 하위 프로세스에 대해 알고 있습니다. 하지만 임의 cat
의(예를 제외하면 의미 없음) 파이프가 진행 중인 하위 프로세스를 cat | cat | cat | ...
알 수 있도록 하는 API는 없습니다 . cat
파이프라인과 그 동료가 누구인지 알아보겠습니다.
% cat | cat -b | cat -e | cat -n
고유한 플래그를 사용하면 어떤 것이 pstree(1)
다른 터미널에 표시되는지 더 쉽게 알 수 있으므로 더 유용합니다.
| \-+= 35276 jhqdoe -zsh (zsh)
| |--- 44661 jhqdoe cat -n
| |--- 03968 jhqdoe cat -b
| |--- 96165 jhqdoe cat -e
| \--= 26975 jhqdoe cat
cat -e
그러나 이것은 파이프가 무엇인지 알려주지 않고 cat -n
, 고양이 가방이 모두 상위 쉘 35276의 프로세스 그룹에 속한다는 것을 알려줍니다.
% ps ao ppid,pid,command | grep '[ ]cat'
35276 44661 cat -n
35276 96165 cat -e
35276 3968 cat -b
35276 26975 cat
어떤 파이프나 설명자가 무엇에 연결되어 있는지 확인하는 pid 또는 명령이 있는 시스템에 있는 경우 /proc
프로세스가 속한 프로세스 그룹에서 무엇이 무엇에 연결되어 있는지 알아낼 수 있습니다. 예를 들어 Linux에서 lsof
유사한 cat 파이프라인을 실행하면 파이프 14301040을 공유하므로 연결 cat -e
하고 명령할 수 있습니다.cat -n
-bash-4.2$ lsof -p 23591 | grep pipe
cat 23591 jhqdoe 0r FIFO 0,9 0t0 14301039 pipe
cat 23591 jhqdoe 1w FIFO 0,9 0t0 14301040 pipe
-bash-4.2$ lsof -p 23592 | grep pipe
cat 23592 jhqdoe 0r FIFO 0,9 0t0 14301040 pipe
따라서 정보를 사용할 수 있더라도 정보를 파악하려면 휴대용이 아닌 도구를 사용하여 많은 정보를 파고 재구성해야 할 수 있습니다.
상위 셸은 입력 후 파이프를 다시 작성하는 방법을 제공할 수 있지만 ZSH 후크 기능은 preexec
실행할 명령을 다시 작성하는 방법을 제공하지 않는 것 같습니다. (이러한 기능은 LISP 매크로를 사용하여 프로그래머가 코드를 다시 작성할 수 있게 하는 방법과 유사할 수 있습니다.) 상위 셸은 하위 프로세스가 파이프를 검사하는 데 사용할 수 있는 일종의 API를 제공할 수도 있지만... 이러한 유형의 추가 사항은 셸에 작성해야 합니다. .
그러나 복잡한 파이프라인을 구축할 수 있습니다.
func | ( cd ... && ... | ( ... | awk ... ) )
이 경우 잘못 func
찾아 awk
반응하지 못하거나 프로세스 파이프라인 검색 기능이 다음 파이프라인 요소에 대한 모든 명령을 재귀적으로 탐색해야 합니다. 이 경우 아마도 즉석 awk
에서일 것입니다. func
또는 이 동작을 설정했다는 사실을 잊어버리고 awk
잘못 수정되어 버그를 찾기 어려울 수도 있습니다...
답변2
적어도 Linux에서는 이 작업을 수행할 수 있었습니다. 이를 보여주는 스크립트는 다음과 같습니다.https://gist.github.com/MatrixManAtYrService/790a4a058bc841b0ceb2eb0263fb5d88
사용 예:
❯ cat -b | ./luigi | jq .
[
{
"pid": "20832",
"name": "cat -b",
"node": {
"write": "5157339",
"read": null
}
},
{
"pid": "20833",
"name": "bash ./luigi",
"node": {
"write": "5157341",
"read": "5157339"
}
},
{
"pid": "20834",
"name": "jq .",
"node": {
"write": null,
"read": "5157341"
}
}
]