$()를 사용하여 저장하지 않고 명령 출력을 인수로 실행하는 방법은 무엇입니까?

$()를 사용하여 저장하지 않고 명령 출력을 인수로 실행하는 방법은 무엇입니까?

이것은 실제로brew search

하지만 단순화를 위해 다음과 같이 한다고 가정하겠습니다.

echo -e 'somedir\n\otherdir'
somedir
otherdir

otherdir이렇게 하지 않고 매개변수로 사용할 수 있나요 ?

ls $(echo -e 'somedir\n\otherdir |tail -n1)
otherdir

목표를 명확히 하기 위해 업데이트됨

더 명확하게 somedir하고 otherdirstdout으로 가려면 그냥 할 수 있습니다.otherdir

출력을 캡처한 $()다음 이에 대해 명령을 실행하지 않습니까?

나는 이것이 가능하다고 생각하지만 그것이 가능하다고 생각하지 않는지 궁금합니다.

답변1

다음을 사용하여 언제든지 xargs출력 스트림을 매개변수 목록으로 변환할 수 있습니다.

printf 'somedir\n\otherdir\n' |
  tail -n1 |
  xargs -rd '\n' ls -l --

-d '\n'행에 GNU 구현이 필요하기 때문에 여기에는 인수가 필요 합니다 xargs.

마지막 줄에 공백, 따옴표, 백슬래시가 없으면 생략할 수 있습니다.

-rls입력이 비어 있으면 실행을 피해야 하는 , 역시 GNU 에서 왔지만 xargs현재는 널리 지원됩니다(그리고 POSIX 표준의 다음 버전에 나타날 예정입니다).


명령 대체를 사용하지 않으려면 bash언제든지 명령 출력 줄을 배열로 읽어 배열의 마지막 요소에서 명령을 실행할 수 있습니다.

readarray -t lines < <(printf 'somedir\notherdir\n')
if (( ${#lines[@]} > 0 )); then
  ls -l -- "${line[@]: -1}"
fi

또는 다음을 사용하십시오 perl.

printf 'somedir\notherdir\n' |
  perl -lne 'exec qw(ls -l --), $_ if eof && $.'

명령 대체를 사용하면 모든 후행 줄 바꿈이 제거되므로 빈 입력과 빈 마지막 줄을 직접 구별할 수 없습니다. 두 경우 모두 확장을 얻고 비워지게 됩니다.

명령 대체 사용의 장점 중 하나는 출력 사용을 결정하기 전에 명령이 성공했는지(종료 상태를 기준으로) 확인할 수 있다는 것입니다.

die() { [ "$#" -eq 0 ] || printf>&2 '%s\n' "$@"; exit 1; }

last_line=$(
  set -o pipefail
  cmd | tail -n 1
) || die "cmd failed"

ls -l -- "$last_line"

또는 grep이를 사용하여 출력이 비어 있지 않은지 확인할 수도 있습니다.

if
  last_line=$(
    set -o pipefail
    cmd |
      tail -n 1 |
      grep '^'
  )
then
  ls -l -- "$last_line"
else
  echo>&2 "Either cmd failed or it didn't produce any output"
fi

grep '^'줄의 시작 부분과 일치합니다. 따라서 출력에 하나 이상의 행이 포함되어 있으면(비어 있는지 여부에 관계없이) true를 반환합니다. 그러나 입력이 개행으로 끝나지 않으면 POSIX 줄 정의에 따라 줄로 간주되지 않으며 grep이 경우 일부 구현이 실패하거나 구분되지 않은 줄을 삭제할 수도 있습니다.

답변2

문법 $()번호구하다아무것. 이는 기본적으로 "이 명령을 실행하고 출력을 인수로 사용한다"는 의미입니다.

귀하의 사용법은 올바른 표준 작업 방식입니다.

(여전히 작동하는) 이전 쉘에서는 백틱(`)이 다음과 같이 작동합니다.

하지만 이는 $()현대적인 방식이며, 기존 방식이 갖고 있던 까다로운 참조 문제도 많이 해결해 줍니다.

예를 들어 거의 모든 곳에서 사용할 수 있습니다.

echo "The current time is: $(date)"
The current time is: Tue Nov 21 22:57:41 EST 2023

관련 정보