Fish 쉘이 프로세스 대체를 함수로 구현하는 것을 보았습니다.
# === Fish shell lang:
function psub
mkfifo $the_pipe
cat >$the_pipe &
echo $the_pipe
# remove pipe when bg job is done
end
# Example:
diff (echo abc | psub) (echo def | psub)
전체 코드:https://github.com/fish-shell/fish-shell/blob/master/share/functions/psub.fish
나는 Fish가 아닌 쉘(mksh)에 대해 이것을 다시 구현하려고 몇 시간 동안 노력했지만 작동하게 할 수 없습니다.
# Executable file: my.psub.sh
the_pipe="$(mktemp /tmp/pipe.XXXXXXXXXX)"
mkfifo $the_pipe
cat >$the_pipe &
echo $the_pipe
# Example:
diff $(echo abc | my.psub.sh) $(echo def | my.psub.sh)
명령 블록. 제가 생각할 수 있는 모든 것을 시도했지만 다음에 어디로 가야 할지 모르겠습니다.
답변1
이것은 약간 어렵지만 실행 가능합니다.
function die {
print -ru2 -- "E: $*"
exit 1
}
function psubin {
local stdin=$(cat; echo .) pipe
pipe=$(mktemp /tmp/psub.XXXXXXXXXX) || die mktemp
# this is racy
rm -f "$pipe"
mkfifo "$pipe" || die mkfifo
(
# don’t block parent
exec <&- >&- 2>&-
# write content to FIFO
print -nr -- "${stdin%.}" >"$pipe"
# signal EOF to reader, ensure it’s not merged
sleep 0.1
:>"$pipe"
# clean up
(sleep 1; rm -f "$pipe") &
) &
print -nr -- "$pipe"
}
diff -u $(echo abc | psubin) $(echo def | psubin)
여기서 내가 가진 문제는 다음과 같습니다.
mkfifo
rm
mktemp
먼저 출력 하지 않으면 불평합니다- mksh는 상위 프로세스와 파일 설명자(stdin, stdout, stderr)를 여전히 공유하는 경우 백그라운드 프로세스를 차단
>&-
합니다>/dev/null
. 사용 중이거나 새 fd로 교체되지 않음) - 백그라운드 프로세스에는 표준 입력이 없기 때문에 해당 내용을 바이트 단위로 정확하게 캐시해야 합니다.
- FIFO(명명된 파이프)를 사용한 EOF는 쉽지 않습니다. 그냥 놔두자... (몇 가지 트릭을 시도하고 비차단 방식으로 FIFO를 열어 판독기가 있는지 확인하고 판독기가 죽을 때까지 EOF 신호를 내보낼 수 있지만 이것으로 충분합니다.현재)
- 사용 후 FIFO를 제거하면 더 좋을텐데...
반면에, 우리가 지금 이 일을 하고 있는 것은 좋은 일입니다. 왜냐하면 결국 나는 이것을 mksh 자체에 구현하고 싶고 , 우리가 그것을 사용할 <(…)
수 없기 때문에 무엇을 주의해야 할지 알아야 할 것이기 때문입니다. /dev/fd/
이식성이 충분하지 않기 때문에 GNU bash와 같습니다.
답변2
이것은 불가능해 보인다:
diff (echo abc | ./my.psub.sh) (echo def | ./my.psub.sh)
실행하기 전에 2개의 하위 쉘을 종료해야 하기 때문에 차단됩니다 diff
.
Fish Shell에서 작동하지만 명령 및 프로세스 대체와 같은 작업을 수행하기 때문일 가능성이 높습니다.매우 다르다그리고그것은 그 자체의 문제이다.
또 다른 옵션은 busybox
"를 따르는 것 입니다.mksh에서 프로세스 교체 솔루션":
busybox diff =(sort ./a) =(sort ./b)