임시 파일 생성, 프로세스 대체, 변수 확장?

임시 파일 생성, 프로세스 대체, 변수 확장?

내가 다음과 같은 일을 하고 있었다면

  1. 임시 파일 만들기

    some process generating output > temp_file
    cat  temp_file
    
  2. 프로세스 교체:

    cat <(some process generating output)
    
  3. 다른 방법:

    cat <<<(some process generating output)
    

이에 대해 몇 가지 질문이 있습니다.

  1. <() >()프로세스 대체나 변수 확장을 위한 데이터 출력 크기에 제한이 있나요?<<<()
  2. 다음 중 가장 빠른 것은 무엇입니까? 아니면 더 빠르게 할 수 있는 방법이 있습니까?

내 ulimit 명령 출력은 다음과 같습니다.

bash-3.00$ ulimit -a
core file size        (blocks, -c) unlimited
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
open files                    (-n) 256
pipe size          (512 bytes, -p) 10
stack size            (kbytes, -s) 8480
cpu time             (seconds, -t) unlimited
max user processes            (-u) 8053
virtual memory        (kbytes, -v) unlimited

답변1

<(cmd)또한 ksh지금은 ,zshbash프로세스 교체.

/dev/fd/n또는 를 지원하는 시스템에서는 /proc/self/fd/n임시 명명된 파이프가 아닌 파이프를 통해 구현됩니다. 어쨌든 그것은 프로세스 간 통신 메커니즘인 파이프 형태입니다.

cmd1 <(cmd2)

(일반 파이프를 사용하여) 다음과 같이 작성할 수 있습니다.

{ cmd2 4<&- | 3<&0 <&4 4<&- cmd1 /dev/fd/3; } 4<&0

또는 (명명된 파이프 사용):

mkfifo /tmp/named_pipe
cmd2 > /tmp/named_pipe & cmd1 /tmp/named_pipe

즉, 두 명령이 동시에 시작되고 파이프와 통신합니다. 일반적으로 이 작업을 수행 cmd2 | cmd1하지만 프로세스 대체는 표준 입력이 아닌 파일 이름에서만 입력을 얻을 수 있거나 cmd1여러 입력이 필요한 상황(예: diff <(cmd1) <(cmd2).

프로세스 수, CPU 시간 또는 메모리와 같은 일반적인 제한 외에 다른 제한은 영향을 미치지 않습니다.

ulimitPIPEBUF의 일부 구현 및 이와 유사한 bash보고서에서는 PIPEBUF ksh가 rlimit가 아니지만 파이프에 대한 쓰기가 원자성으로 보장되는 최대 크기이므로 이와 관련이 없습니다. 파이프 자체의 크기(Linux에서 @dsmsk80이 64kB를 보고함) 자체는 실제로 제한 사항이 아닙니다. cmd2파이프에서 읽기를 중단한 후에도 파이프에 쓸 수 있다고 말합니다 .cmd1

하지만cmd1읽다이 파일에서. 파이프이기 때문에 파일에 쓰거나 파일을 앞뒤로 볼 수 없습니다.

zsh일반 임시 파일을 사용하는 세 번째 형태의 명령 대체가 있습니다.

cmd1 =(cmd2)

cmd1호출은 출력이 포함된 임시 파일로 이루어집니다 cmd2. 이 경우 cmd1실행뒤쪽에동시 대신 cmd2. 파일 크기 제한에 도달할 수 있습니다.

<<<(...)나는 연산자를 구현하는 쉘을 알지 못합니다 . 그러나 (Unix 포트의 동일한 연산자에서 영감을 얻은) <<<연산자는 및 의 최신 버전에서도 발견됩니다 . zsh이는 herestring이라고 하는 heredoc 연산자의 변형입니다.rcksh93bash<<

존재하다:

cmd <<< something

표준과 동일:

cmd << EOF
something
EOF

쉘은 임시 파일을 something\n컨텐츠로 생성하여 이를 새 프로세스에 표준 입력으로 제공하고 파일 링크를 해제한 후 cmd새 프로세스에서 실행합니다. 다시 말하지만, 이는 일반 파일이므로 최대 파일 크기 제한에 도달할 수 있습니다.

이제 <<<연산자를 (명령 대체)와 결합하여 $(...)어떤 방식으로든 연산자를 에뮬레이트 할 수 있습니다 zsh.=(...)bashksh93

cmd1 <<<"$(cmd2)"

cmd2파이프로 리디렉션된 표준 출력으로 실행됩니다. 파이프의 다른 쪽 끝에서 쉘은 출력을 읽고 cmd2후행 줄 바꿈을 제외하고 저장하고 임시 파일에 줄 바꿈을 추가하고 cmd1해당 임시 파일을 호출하여 stdin으로 읽기 위해 엽니다(또 다른 제한 사항이 있음에 유의) 출력에 NUL 문자가 포함되어 있으면 작동하지 않습니다 cmd2.

처럼 되려면 =(...)다음과 같이 작성해야 합니다.

cmd1 /dev/fd/3 3<<<"$(cmd3)"

쉘은 임시 파일에 쓰기 전에 메모리에 있는 cmd3의 전체 출력을 읽어야 하므로 최대 파일 크기 외에도 메모리 사용량 제한에 도달할 수도 있습니다.

또한 버전 5부터는 bash호출 전에 임시 파일에 대한 쓰기 권한이 제거되므로 파일을 수정 cmd1해야 하는 경우 cmd1다음을 사용하여 문제를 해결해야 합니다.

{
  chmod u+w /dev/fd/3 && # only needed in bash 5+
  cmd1 /dev/fd/3
} 3<<<"$(cmd3)"

답변2

<(cmd)Bash 프로세스 교체는 >(cmd)시스템이 명명된 파이프를 지원하는 경우 구현됩니다. 명령은 cmd파이프에 연결된 입력/출력으로 실행됩니다. 예를 들어 실행하면 cat <(sleep 10; ls)디렉터리에서 생성된 파이프라인을 찾을 수 있습니다 /proc/pid_of_cat/fd. 이 명명된 파이프는 현재 명령( cat)에 매개변수로 전달됩니다.

파이프의 버퍼 용량은 명령의 표준 입력에 제로 데이터를 보내는 (아무 작업도 수행하지 않음) dd명령을 영리하게 사용하여 추정할 수 있습니다 . sleep분명히 프로세스는 버퍼가 가득 차도록 잠시 동안 잠자기 상태가 될 것입니다.

(dd if=/dev/zero bs=1 | sleep 999) &

잠시 기다린 후 USR1프로세스에 신호를 보냅니다 dd.

pkill -USR1 dd

이로 인해 프로세스가 I/O 통계를 인쇄합니다.

65537+0 records in
65536+0 records out
65536 bytes (66 kB) copied, 8.62622 s, 7.6 kB/s

내 테스트 사례에서 버퍼 크기는 64kB( 65536B)입니다.

확장 프로그램은 어떻게 사용하나요 <<<(cmd)? 나는 이것이 확장되어 표준 입력의 명령에 전달되는 문서의 변형이라는 것을 알고 있습니다.

크기에 관한 문제를 밝힐 수 있기를 바랍니다. 속도에 관해서는 확실하지 않지만 두 방법 모두 비슷한 처리량을 제공할 것이라고 가정합니다.

관련 정보