내가 다음과 같은 일을 하고 있었다면
임시 파일 만들기
some process generating output > temp_file cat temp_file
프로세스 교체:
cat <(some process generating output)
다른 방법:
cat <<<(some process generating output)
이에 대해 몇 가지 질문이 있습니다.
<()
>()
프로세스 대체나 변수 확장을 위한 데이터 출력 크기에 제한이 있나요?<<<()
- 다음 중 가장 빠른 것은 무엇입니까? 아니면 더 빠르게 할 수 있는 방법이 있습니까?
내 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
지금은 ,zsh
bash
프로세스 교체.
/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 시간 또는 메모리와 같은 일반적인 제한 외에 다른 제한은 영향을 미치지 않습니다.
ulimit
PIPEBUF의 일부 구현 및 이와 유사한 bash
보고서에서는 PIPEBUF ksh
가 rlimit가 아니지만 파이프에 대한 쓰기가 원자성으로 보장되는 최대 크기이므로 이와 관련이 없습니다. 파이프 자체의 크기(Linux에서 @dsmsk80이 64kB를 보고함) 자체는 실제로 제한 사항이 아닙니다. cmd2
파이프에서 읽기를 중단한 후에도 파이프에 쓸 수 있다고 말합니다 .cmd1
하지만cmd1
읽다이 파일에서. 파이프이기 때문에 파일에 쓰거나 파일을 앞뒤로 볼 수 없습니다.
zsh
일반 임시 파일을 사용하는 세 번째 형태의 명령 대체가 있습니다.
cmd1 =(cmd2)
cmd1
호출은 출력이 포함된 임시 파일로 이루어집니다 cmd2
. 이 경우 cmd1
실행뒤쪽에동시 대신 cmd2. 파일 크기 제한에 도달할 수 있습니다.
<<<(...)
나는 연산자를 구현하는 쉘을 알지 못합니다 . 그러나 (Unix 포트의 동일한 연산자에서 영감을 얻은) <<<
연산자는 및 의 최신 버전에서도 발견됩니다 . zsh
이는 herestring이라고 하는 heredoc 연산자의 변형입니다.rc
ksh93
bash
<<
존재하다:
cmd <<< something
표준과 동일:
cmd << EOF
something
EOF
쉘은 임시 파일을 something\n
컨텐츠로 생성하여 이를 새 프로세스에 표준 입력으로 제공하고 파일 링크를 해제한 후 cmd
새 프로세스에서 실행합니다. 다시 말하지만, 이는 일반 파일이므로 최대 파일 크기 제한에 도달할 수 있습니다.
이제 <<<
연산자를 (명령 대체)와 결합하여 $(...)
어떤 방식으로든 연산자를 에뮬레이트 할 수 있습니다 zsh
.=(...)
bash
ksh93
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)
? 나는 이것이 확장되어 표준 입력의 명령에 전달되는 문서의 변형이라는 것을 알고 있습니다.
크기에 관한 문제를 밝힐 수 있기를 바랍니다. 속도에 관해서는 확실하지 않지만 두 방법 모두 비슷한 처리량을 제공할 것이라고 가정합니다.