프로세스 교체 없이 쉘에서 프로세스 교체를 구현하는 방법(bash 스크립트 사용)

프로세스 교체 없이 쉘에서 프로세스 교체를 구현하는 방법(bash 스크립트 사용)

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)

여기서 내가 가진 문제는 다음과 같습니다.

  • mkfiform 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)

관련 정보