cmd2`cmd1` 및 cmd1 xargs cmd2 |

cmd2`cmd1` 및 cmd1 xargs cmd2 |

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

구현에 따라 cmdstdin은 /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])

관련 정보