한 프로그램의 표준 입력을 어떻게 다른 인수로 인수로 전달할 수 있습니까?


17

프로그램이 존재한다고 가정 해 봅시다. 두 개의 인수가 필요합니다. 입력 파일 및 출력 파일.

이 출력 파일을 디스크에 저장하지 않고 stdin다른 프로그램으로 바로 전달하려면 어떻게해야합니까 ? 이것을 달성 할 수있는 방법이 있습니까?

리눅스에서 나는 많은 명령을 출력 파일 인수로 '-'를 전달하는 옵션을 제공합니다. 이는 위에서 지정한 것을 수행합니다. stdin프로그램의 인수를 인수로 전달할 수 없기 때문 입니까? 그렇다면 어떻게해야합니까?

이것을 사용하여 이미지를 생성하는 방법의 예는 다음과 같습니다.

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" stdin(echo)

내가 사용하는 쉘은 bash입니다.


1
cat <file | cmd /dev/fd/0대부분의 유니스에서 작동합니다.
mikeserv

나를 위해 작동하지 않습니다. 그것을 시도했다 : cat < README.txt | cp /dev/fd/0. 그것은 말했다cp: missing destination file operand after ‘/dev/fd/0’ Try 'cp --help' for more information.
Dziugas

1
program input-file /dev/stdout | another-program? 또한 echostdin에서 아무것도 읽지 않습니다.
yaegashi

1
@Dziugas-물론 아닙니다- cp파일을 어디에도 넣을 수 없습니다 . echo 1 2 3| cp /dev/fd/0 /dev/tty인쇄 1 2 3합니다. 그런데 대부분의 경우 /dev/fd/[num]보다 작동하기 쉽습니다 /dev/std(in|out|err). 어디에서 작업 할 수 있는지에 대해서는 파일 디스크립터 링크의 이식성을 참조하십시오 .
mikeserv

1
좋은 UNIX 프로그램은 표준 출력에 기록하여 사용자가 파일로 리디렉션할지 또는 다른 명령으로 파이프를 리디렉션할지 결정하도록합니다.
Jorge Bucaran

답변:


13

프로그램이 검색 할 수 없어도 파일 디스크립터에 대한 쓰기를 지원하는 경우 /dev/stdout출력 파일로 사용할 수 있습니다 . 이것은 /proc/self/fd/1내 시스템에 대한 심볼릭 링크 입니다. 파일 디스크립터 1이 stdout입니다.


이것은 내 질문을 해결했습니다. 프로그램이 필요로 할 때 그렇게 할 수있는 방법이 없습니까?
Dziugas

3
디스크 액세스를 방지하려는 경우 / dev / shm /에 파일을 쓸 수 있지만 파일 시스템에 파일을 원하지 않으면 내가 아는 한 찾을 방법이 없습니다. 파이프. 순방향을 찾는 것은 해당 시점에 도달 할 때까지 메모리의 모든 것을 버퍼링해야한다는 것을 의미하며, 역방향을 찾는 것은 메모리의 모든 것을 버퍼링 한 것을 의미합니다.
TiCPU

pdftotext-/ dev / stdout을 지원하지 않는 시스템이나 stdout이 아닌 Linux에서 / dev / stdout이 예상대로 작동하지 않는 시스템에서도 작동하는 다른 유틸리티 도 마찬가지입니다. 파이프). pdftotext file.pdf - | wc -c
Stéphane Chazelas

11

로부터 pdftotext매뉴얼 페이지

text-file이 '-'인 경우 텍스트는 stdout으로 전송됩니다.

따라서이 경우 필요한 것은 다음과 같습니다.

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" -

또는 이것을 다른 프로그램의 STDIN으로 파이프하려는 경우 :

pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" - | another_prog

-STDIN에서 입력하거나 STDOUT으로 출력하려는 ​​경우 많은 유틸리티 (pdftotext 포함)가 파일 이름 대신 사용 하는 규칙입니다. 그러나 모든 유틸리티가이 규칙을 따르는 것은 아닙니다. 이 경우 bash에서 이것을 수행하는 관용적 방법은 프로세스 대체 를 사용하는 것입니다 .

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( cat )

여기 >( ) 동작은 대체로 전달 된 파일처럼 작동 my_utility하지만 실제 파일 대신 스트림이 포함 된 프로세스, 즉 cat의 stdin으로 파이프됩니다. 따라서 여기에서 텍스트는 필요에 따라 출력되어야합니다.

이와 같은 포럼 에서는 cat거의 항상 UUOC 알람 벨 을 사용합니다. 유틸리티가 지원하지 않으면-cat 경우,이 방법을 유용하게 사용할 수 하지만,이없이 프로세스를 대체 할 수있는 방법이 있다면 cat, 나는 모두 귀입니다 ;-).

그러나 (질문대로) 스트림의 최종 목적지가 다른 프로그램의 STDIN이면 다음을 cat제거 할 수 있습니다.

my_utility "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf" >( another_prog )

2
그리고 내가 한 번 후퇴하다 수 있도록 더 다음의 경우 prog2표준 출력으로 쓰기는 더 나은보다 , 때문에 위한 형태로 대기 에 (즉, 쉘 문제 다음 프롬프트 이후에, 예를 들어, 다음 명령 (으로 진행하기 전에 완료 또는 )), 그동안 -less 양식은 완료 될 때 까지만 기다립니다 . 또한 양식 다음에의 종료 상태는 이고, 다른 경우 의 종료 상태는 입니다. (당신은 돈을 지불하고 선택을합니다.)prog1 input_file >( cat ) | prog2prog1 input_file >( prog2 )catprog2;&&catprog1cat$?prog2$?prog1
Scott

4

쉘에서 지원하는 그와 같은 조작을 수행하는 가장 간단한 방법은 사용하는 것입니다 경우 프로세스 대체 : <(…)>(…). 이것은 bash, zsh 및 ksh 및 가능하면 다른 쉘에서 작동합니다. 예를 들면 다음과 같습니다.

$ sort <(printf "b\nc\na\n")
a
b
c
$ ls
foo
$ cp <(find . -name foo) bar
$ ls
bar  foo

그러나 이것은 pdftotext텍스트 파일에 저장하기 때문에 상태 예제에서 도움이되지 않습니다 . @TiCPU에서 제안한대로을 -사용 /dev/stdout하는 것이 최선의 선택이지만 다른 쉘 기능을 사용할 수도 있습니다. 구문 !:N은 이전 명령의 N 번째 인수를 나타냅니다. 따라서 다음을 수행 할 수 있습니다.

$ pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"  out.txt
$ cat !:2

1
cat <()일부 상황에서는 유용 할 수 있음에 동의 하지만이 시나리오에서는 전혀 작동하지 않습니다. 문제는 (OP에 매우 잘 설명되어 있지 않다는 것을 인정해야 함) 입력 파일출력 파일 이라는 pdftotext두 가지 인수 가 필요하다는 것 입니다. 두 번째 인수가 없으면 아무것도 생성하지 않으므로 아무것도 반환하지 않습니다. Digital Trauma가 대답 한 것과 같은 두 번째 주장으로 명령을 속일 수 있지만 여기서는 의미가 없습니다. 출력 파일 이름 으로 사용하는 것이 가장 좋은 경우는 분명 합니다. cat <(pdftotext "file.pdf")pdftotext>(cat)cat <()pdftotext-
jimmij

1
@Scott 내 답변은 어떻게 UUOC입니까? 고양이없이이 공정 대체를 어떻게 하시겠습니까? >( )내부의 프로세스에 효과적으로 스트림을 파이프합니다. 따라서 실제로 cat그 스트림을 출력 하려면 여기 가 필요 합니다. 일반적으로 우리는 같은 것을 할 수 있어야 pdftotext input.pdf -하지만 파일 대신 stdout에 직접 출력 pdftotext하는 -매개 변수를 지원하지 않는 것 같습니다 . 시도하십시오.
디지털 외상

1
@DigitalTrauma 그것은 uuoc이 아닙니다. 인쇄하는 경우에는 고양이가 가장 빠르지 만 실제로는 다른 명령을 사용 >(grep something)하여 더 유용하다고 생각합니다. BTW, 내 pdftotext 3.04 할 일 지원 -난 그래서 출력 파일로는, 약간은 전체 토론에 의해 놀라게했다.
jimmij

1
@terdon 나는 stickler가 싫어하지만 이것은 효과가없는 것 같습니다. 특히 running pdftotext "C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.pdf"이라는 파일과 출력 파일을 넣는 running 과 다르지 C BY BRIAN W KERNIGHAN & DENNIS M RITCHIE.txt않지만 다른 프로그램으로 파이프하기 위해 STDOUT으로 출력되는 텍스트는 없습니다.
디지털 외상

1
@DigitalTrauma는 stickler가 아닙니다! 내가 바보 야. 지적 해 주셔서 감사하며 실수를 지적 할 때 사과하지 마십시오. 나는 오히려 내 실수가 나에게 지적 했으므로 모든 모호한 영광으로 그것을 떠나는 것보다 무언가를 배우기를 원할 것입니다.
terdon

-2
cmd tty

tty에 연결된 터미널의 이름을 반환합니다 stdout.


이것이 명령을 결합하는 것에 관한 질문에 어떻게 대답하는지 잘 모르겠습니다. 아마도 당신은 그것을 달성 할 수있는 방법의 예를 통해 확장 할 것입니다.
dhag

tty터미널 이름 을 확인한 다음 해당 파일을 출력으로 사용한다고 가정합니다 pdftotext file.pdf /dev/pts/2. 이 경우 동의합니다.
jimmij

그것은 약식 / 자동화 될 수있다 ; 일반적으로prog1  input_file $(tty)prog1  input_file /dev/tty . 그러나이 방법은 목표의 출력을 표시하는 것으로 가정 prog1(터미널에서 즉,), 그리고 그 문제는 (참조 요구되는 것이 아닙니다 의견terdon의 답변을 질문의 의미에 대한 몇 가지 설명을 위해).
Scott
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.