find
파일을 찾고 찾은 경로를 에 전달하려고 합니다 sqlite3
. sqlite>
명령이 다음 형식을 취하는 경우에만 프롬프트가 표시됩니다.
sqlite3 `find . -type f -iname "*.db" | head -n1`
그러나 다음 형식은 작동하지 않습니다.
find . -type f -iname "*.db" | head -n1 | xargs sqlite3
find . -type f -iname "*.db" | head -n1 | xargs -I% sh -c 'sqlite3 %;'
다음 명령이 전혀 작동하지 않는 이유는 무엇입니까?
답변1
존재하다:
... | xargs cmd
구현에 따라 cmd
stdin은 /dev/null
또는 해당 파이프입니다. 파이프를 통해 손실되므로 외부 표준 입력이 될 수 없습니다.
$ echo /proc/self/fd/0 | gnu-xargs ls -ld
lr-x------ 1 me me 64 Dec 11 22:04 /proc/self/fd/0 -> /dev/null
$ echo /proc/self/fd/0 | busybox-or-solaris-...-xargs ls -ld
lr-x------ 1 me me 64 Dec 11 22:04 /proc/self/fd/0 -> pipe:[99839]
두 경우 모두 sqlite3
입력 내용을 읽을 수 없습니다.
이것:
sqlite3 `find . -type f -iname "*.db" | head -n1`
이 명령은 에서 반환한 첫 번째 파일 경로의 첫 번째 줄을 가져와 find
분할하고 $IFS
와일드카드를 수행한 다음 결과 단어를 별도의 인수로 sqlite3에 전달합니다. 이것은 거의 의미가 없습니다.
GNU 사용 find
(아마도 사용 중인 GNU -iname
):
sqlite3 "$(find . -type f -iname "*.db" -print -quit)"
처음 발견된 파일을 인쇄한 후 종료 -exit
하려면 Tell을 사용합니다 . find
우리는 현대적인 형태의 명령 대체를 사용 $(...)
하고 명령 대체를 인용하여 분할+glob 부분을 건너뜁니다(말이 안 됨).
다음을 사용할 수도 있습니다(여전히 GNU에만 해당).
find . -type f -iname '*.db' \( -exec sqlite3 {} \; -o -true \) -quit
(종료 상태는 사라지지만 sqlite3
)
그리고 zsh
:
setopt extendedglob # best in ~/.zshrc
sqlite3 ./**/*.(#i)db(D.[1])