제가 이해한 바는 pipe
예를 들어,
command1 | command2
command1
출력을 으로 보냅니다 command2
. 그러나 이것이 효과가 있기를 바랍니다.
echo "tmp.pdf" | evince
그러나 그것은 진실이 아니다. echo "tmp.pdf"
출력은 어디로 전송되나요?
답변1
당신의 이해가 정확합니다. 이 시퀀스는 command1 | command2
출력(STDOUT)을 command1
입력(STDIN)으로 보냅니다 command2
. 명령 evince
이 작동하지 않는 이유는 evince
STDIN에서 파일 이름을 허용하지 않기 때문입니다.
답변2
파이프는 읽기 위해 여는 프로그램에 출력을 보냅니다. 쉘 파이프에서 이는 귀하의 예에 있는 파이프 기호 오른쪽에 있는 프로그램입니다 evince
.
tmp.pdf
표준 입력에 표시할 파일 이름을 보내고 있습니다 . 그러나 evince는 표준 입력에 관심이 없습니다. 파일에서 작동하는 모든 프로그램과 마찬가지로 파일 이름이 명령줄 인수로 전달될 것으로 예상합니다. 명령줄에 파일 이름을 전달하지 않으면 파일을 여는 기능을 제공합니다. 명령줄 인수는 표준 입력과 동일하지 않습니다. 인간은 사물에 따라 서로 다른 입력 기관을 가지고 있으며(예를 들어 코를 통해 음식을 먹을 수는 없음), 마찬가지로 프로그램에도 목적에 따라 정보를 받는 방법이 다릅니다.
Evince는 읽을 수 있습니다문서(파일 이름 아님) 표준 입력: evince /dev/stdin <"tmp.pdf"
. (일부 Unix 변형에서는 작동하지 않을 수 있습니다.) 파일 이름은 /dev/stdin
"표준 입력으로 연 모든 파일"을 의미합니다. 명령줄에서 사용되는 프로그램은 일반적으로 파일 이름을 지정하지 않고 표준 입력을 읽지만 GUI 프로그램은 일반적으로 읽지 않습니다. Evince cat tmp.pdf | evince /dev/stdin
는 페이지 사이를 탐색할 때 파일을 앞뒤로 볼 수 있어야 하기 때문에 파이프에서 오는 데이터(예를 들어 작동하지 않음)가 아닌 일반 파일만 열 수 있습니다 .
답변3
최근에 제가 깨달았듯이 다음과 같이 이 문제를 해결할 수 있습니다. 먼저 찾기 명령을 사용하여 evince에서 열려는 파일의 경로를 찾으세요. 이 결과는 evince에 매개변수로 전달됩니다. 파일 이름이 abc_xyz.pdf이고 이를 열고 싶다고 가정합니다. 그런 다음 - 를 수행할 수 있습니다
evince "$(sudo locate xyz | grep abc)"
. pdf 파일 이름에 공백이 포함되어 있으면 큰따옴표가 필요합니다. 즉 , 결과를 추가로 필터링하기 위해 $(sudo locate xyz | grep abc)
다른 코드( 로 연결됨 sudo locate xyz
)를 사용하는 이유입니다. grep abc
하지만 여기에는 문제가 있습니다. 즉, Locate 를 실행하여 계속 업데이트해야 한다는 것입니다 sudo updatedb
. pdf의 위치를 새로운 디렉토리로 변경했다고 가정하면 itz 데이터베이스가 아직 업데이트되지 않았기 때문에 located가 itz의 새 위치를 찾을 수 없습니다. 그러나 실시간 검색 작업을 수행하려면 "and" 조건과 함께 "find" 명령을 사용할 수 있습니다. 예를 들어 다음과 같이 할 수 있습니다.
evince "$(find ~/ -iname "*abc*" -a -iname "*xyz*" -type f)"
-iname
대소문자를 구분하지 않는 검색과 -a
yes 및 조건을 위해 evince.here 인수에 인수로 전달합니다 . -type f
파일만 반환됩니다.