내 Ubuntu 컴퓨터에는 다음 줄이 포함된 보기 흉한 bash 스크립트가 있습니다.
search_command="find -L $(printf "%q" "$search_folder") \( ! -regex '.*/\..*/..*' \) -mindepth 1 2> /dev/null"
for i in "${IGNOREENDINGS[@]}"
do
search_command="$search_command -not -name \"*$i\""
done
search_command="$search_command | sed 's|^${search_folder}/\?||'"
choice=$(eval "$search_command"|fzf -q "$file_query" -1 --preview "preview $search_folder {}")
fzf
이 스크립트를 사용하면 명령 일치를 사용하여 파일을 선택할 수 있습니다 GNU find
.
여기에는 다음과 같은 문제가 있습니다. 스크립트 인터페이스에서 파일을 선택하자마자 fzf 인터페이스가 닫히므로 완료된 것처럼 보이지만 여전히 명령이 완료될 fzf
때까지 기다려야 합니다 (validation 포함 ). 장기. 왜 내가 원하는 파일이 거의 항상 즉시 나타나는지 잘 모르겠습니다.find
top
XY 문제를 피하기 위해 위에 몇 줄을 추가했습니다. 동일한 기능과 더 빠른 실행을 제공하는 모든 것이 만족스럽습니다.
답변1
여기에는 두 가지 가능성이 있습니다. fzf
파일을 선택할 때 실제로 종료가 없거나 파일을 선택할 find
때 종료가 없습니다 fzf
. 후자인 경우 find
종료할 때 수동으로 닫는 스크립트를 작성할 수 있습니다.fzf
Linux에서 파이프가 작동하는 방식은 find
파이프에 쓰기를 시도하고 실패할 때까지 파이프가 파이프에서 아무것도 읽지 않는다는 사실을 알지 못합니다. 그래서 파일을 선택하면뒤쪽에 find
찾고 있는 모든 것을 찾았으면 find
파이프에 더 이상 쓰기가 수행되지 않으므로 종료하기 전에 전체 파일 시스템이 반복됩니다.
예를 들어, 임의의 파일을 생성한 /
다음 실행하면 find / -name $random_file_name | head -n 1
매우 빠르게 얻을 수 있는 모든 출력을 얻을 수 있지만 프로그램은 오랫동안 계속 실행됩니다.
이 문제를 해결하는 한 가지 방법은 프로세스가 완료되었을 때 프로세스를 직접 종료하는 것입니다. 특정 경우에 가장 쉬운 방법은 아마도 명명된 파이프일 것입니다.
tmp_fifo=`mktemp -u`
mkfifo "$tmp_fifo"
eval "$search_command" > "$tmp_fifo" &
choice="$(fzf -q "$file_query" -1 --preview "preview $search_folder {}" < "$tmp_fifo")" ; kill $!
rm "$tmp_fifo"
그러면 임시 명명된 파이프가 생성되고 거기에 find
쓰고 fzf
읽습니다. 그러나 fzf
종료할 때 kill $!
실행은 $!
마지막으로 시작된 백그라운드 프로세스를 나타냅니다. 이 경우에는 find
.
답변2
또 다른 대답좋아보이는데, FIFO를 관리해야 한다는게 단점이네요. 배쉬와 함께coproc
FIFO의 이름을 지정하지 않고도 문제를 해결할 수 있습니다.
(참고: 이 답변이 특정 문제가 아닌 일반적인 문제를 해결하도록 하기 위해 변수 eval
및 유사한 항목을 제거했습니다.)
coproc find ... # this silently runs in background, no `&' nor explicit redirection needed
<&${COPROC[0]} fzf ... # piping from `find' to `fzf'
kill $! # killing the last background process, i.e. `find'