임시 데이터 용 의사 파일


98

나는 종종 반복되는 방식으로 파일 (예 : wdiff)의 입력 만 허용하는 명령 줄 프로그램에 비교적 짧은 문자열 데이터 (여러 줄이 될 수 있음)를 공급하려고합니다. 물론 하나 이상의 임시 파일을 작성하고 거기에 문자열을 저장 한 후 파일 이름을 매개 변수로 사용하여 명령을 실행할 수 있습니다. 그러나 데이터가 실제로 디스크에 기록되면이 절차가 매우 비효율적 인 것처럼 보이고이 절차를 여러 번 반복하면 디스크가 손상 될 수 있습니다 (예 : 긴 줄의 긴 텍스트를 제공하려는 경우) 파일을 wdiff로 파이프와 같은 의사 파일을 사용하여 실제로 디스크에 데이터를 쓰지 않고 데이터를 임시로 저장하거나 임계 길이를 초과하는 경우에만 데이터를 쓰는 등 권장하지 않는 방법이 있습니까? wdiff는 두 가지 인수를 취합니다.wdiff <"text".


이것을 통해 해결할 수 있습니까 xargs?
NN

몰라요, 그러나 그것은 나에게 분명하지 않습니다. 내가 이해 xargs하는 한 명령의 파일 문자열 인수에서 입력 줄을 만들 것입니다. 그러나 나는 그 반대가 필요하다.
highsciguy

@rahmu 살펴 보았지만 문제 설정이 조금 다르다고 생각합니다. 적어도 나는 대답이 어떻게 도움이 될지 모르겠습니다. 임시 파일을 올바르게 생성하기 위해 허용되는 대답은 실제로 파일을 작성하지 못하게하는 버퍼링이 없으면 피하고 싶지 않은 것입니다. 임시 파일의 작동 방식에 대한 이해가 제한적입니다!
highsciguy

무슨 일이야 echo $data_are_here | dumb_program?
vonbrand

1
이것은 하나의 입력 파일 만 지원하며 모든 프로그램이 stdin에서 읽지는 않습니다.
highsciguy

답변:


55

명명 된 파이프를 사용하십시오 . 예를 들어 :

mkfifo fifo
echo -e "hello world\nnext line\nline 3" > fifo

이 명령 -e은 echo를 통해 개행 이스케이프 ( \n) 를 올바르게 해석합니다 . 파이프가 데이터를 읽을 때까지 쉘이 정지됩니다.

다른 디렉토리를 동일한 디렉토리에서여십시오 :

cat fifo

에코를 읽고 다른 쉘을 해제합니다. 파이프는 디스크에 파일 노드로 존재하지만 파이프를 통과하는 데이터는 그렇지 않습니다. 그것은 모두 메모리에서 일어난다. &에코를 배경 ( ) 할 수 있습니다 .

파이프에는 64k 버퍼 (Linux의 경우)가 있으며 소켓과 마찬가지로 소켓이 가득 차면 기록기를 차단하므로 기록기를 조기에 죽이지 않는 한 데이터가 손실되지 않습니다.


고마워, 이것은 두 개의 명명 된 파이프와 wdiff 와도 작동합니다. 그러나 파이프로 사용할 수있는 특정 (소량) 메모리가 버퍼로 이해되고 있다고 생각했습니다. 버퍼 크기를 초과하면 어떻게됩니까?
highsciguy 2013

그 문제에 대한 마지막 단락을 추가했습니다.
goldilocks

3
/tmp대부분의 배포판 tmpfs에서는 RAM에 있는 파일 시스템 을 사용하도록 구성됩니다 . 파일을 쓸 때 /tmpRAM에 직접 들어가 므로 빠르게 액세스하고 여러 번 다시 작성 해야하는 반 복원성 파일에 대한 좋은 대답입니다.

129

Bash에서는 command1 <( command0 )리디렉션 구문을 사용할 수 있습니다. 리디렉션 구문은 command0stdout 을 리디렉션 command1하고 파일 이름을 명령 줄 인수로 사용하는 파일에 전달합니다. 이것을 프로세스 대체 라고 합니다 .

파일 이름 명령 줄 인수를 사용하는 일부 프로그램은 실제로 실제 임의 액세스 파일이 필요하므로이 기술은 해당 기능을 사용할 수 없습니다. 그러나 다음과 같이 작동합니다 wdiff.

user@host:/path$ wdiff <( echo hello; echo hello1 ) <( echo hello; echo hello2 )
hello
[-hello1-]
{+hello2+}

백그라운드에서 이것은 FIFO를 작성하고 내부의 명령을 FIFO로 파이프 한 <( )다음 FIFO의 파일 디스크립터를 인수로 전달합니다. 무슨 일이 일어나고 있는지 확인하려면 echo아무 것도하지 않고 인수를 인쇄하기 위해 함께 사용하십시오.

user@host:/path$ echo <( echo hello )
/dev/fd/63

명명 된 파이프를 만드는 것이 더 유연하지만 (여러 프로세스를 사용하여 복잡한 리디렉션 논리를 작성하려는 경우) 많은 목적으로 충분하고 사용하기가 더 쉽습니다.

>( )출력으로 사용하고자 할 때 의 구문 도 있습니다. 예 :

$ someprogram --logfile >( gzip > out.log.gz )

관련 기술 은 Bash 리디렉션 치트 시트 를 참조하십시오 .


이것은 KSH에서 지원되지 않습니다
chanchal1987

5
ksh가 이것을 발명했습니다. 지원하지 않는 ksh 변형 을 사용하고 있습니다
Neil McGuigan

2
파일 이름 명령 줄 인수를 사용하는 일부 프로그램은 실제로 실제 임의 액세스 파일이 필요하므로이 기술은 해당 기능을 사용할 수 없습니다. 이 경우에 무엇을합니까? 예를 들어 ssh -F <(vagrant ssh-config) default정말 좋지만 아쉽습니다.
Sukima

10

wdiff는 2 개의 파일 이름 인수가 필요하기 때문에 특별한 경우이지만, 1 개의 인수 만 필요하고 파일 이름 인수 이외의 것을 취하지 않는 모든 명령에는 2 가지 옵션이 있습니다.

  • 파일 이름 '-'(즉, 빼기 기호)는 약 1/2의 시간 동안 작동합니다. 문제의 명령과 명령 개발자가 해당 사례를 잡아서 예상대로 처리하는지 여부에 달려있는 것 같습니다. 예 :

    $> ls | 고양이-

  • 리눅스에 존재하는 / dev / stdin이라는 psuedo 파일이 있으며 파일 이름이 명령에 절대적으로 필요한 파일로 사용될 수 있습니다. 명령에서 특별한 파일 이름 처리가 필요하지 않기 때문에 작동하기 쉽습니다. fifo가 작동하거나 bash 프로세스 대체 방법이 작동하는 경우에도 작동하며 셸과 관련이 없습니다. 예 :

    $> ls | 고양이 / dev / stdin


1
less and openssl like / dev / fd / NUM 대신 / dev / stdin :-)
eel ghEEz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.