몇 줄을 인쇄하는 함수가 있는데 이를 다른 함수의 인수로 사용하고 싶습니다.
lsx() {
echo 1 is one
echo 2 are two
}
somefun() {
for arg in "$@"; do
echo "arg='$arg'"
done
}
somefun()
from 라인을 lsx()
매개변수로 사용하여 어떻게 "우아하게" 전화를 걸 수 있나요 ?
지금 내가 하고 있는 일은 루프를 사용하여 행을 반복하고 (편집: while+subshell로 인해 작동하지 않습니다). 나는 간단한(또는 심지어 이식 가능한?) 방법이 있어야 한다고 생각하지만, 하나도 알아낼 수 없습니다.while
행을 배열에 저장하는 것입니다. 그러나 이것은 보기에도 좋지 않고 너무 효율적입니다.
( somefun
외부 명령인 경우 다음을 사용합니다.매개변수그러나 그것은 진실이 아니다. )
답변1
xargs 없음
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one'
arg='2 are two'
IFS
전역이 아닌 로컬 변경이 이루어지도록 하위 쉘이 사용됩니다 .
한정: 이로 인해 출력이 경로 이름 확장의 영향을 받게 되며 lsx
이는 문제가 될 수도 있고 그렇지 않을 수도 있습니다.
xargs로
xargs를 사용하여 쉘 기능에 액세스하려면 쉘을 실행해야 합니다. 서브셸에 액세스하려면 somefun
먼저 이를 내보내야 합니다. 그러므로:
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one'
arg='2 are two'
첫 번째 인수는 오류 메시지의 프로그램 이름 bash
에 할당 되어 사용됩니다. $0
어떤 단어라도 가능합니다. 여기서는 SomeFun
.
경로 이름 확장 문제의 예
$ lsx() { echo '1 is one*'; echo '2 are two*'; }
$ touch '1 is one'{1..3} two{a..c}
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one1'
arg='1 is one2'
arg='1 is one3'
arg='2 are two*'
보시다시피 출력의 첫 번째 줄은 세 줄로 확장됩니다.
쉘이 먼저 실행됨분사출력에 $(lsx)
. IFS가 개행으로 설정되어 있으므로 출력이 여러 줄로 분할됩니다. 그런 다음 쉘이 실행됩니다.경로명 확장. glob 과 일치하는 파일이 있기 때문에 1 is one*
glob은 이러한 이름의 목록으로 확장됩니다. 이 예에서는 glob과 일치하는 파일이 없으므로 2 is two*
glob이 확장되지 않습니다. (기본 IFS에서는 2 is two*
세 단어로 분할되고 세 번째 단어는 file 및 과 일치 twoa
합니다 twob
. twoc
)
이 xargs
방법은 경로 이름 확장을 방지합니다.
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one*'
arg='2 are two*'
답변2
간단한 솔루션:
IFS="
"
somefun $(lsx)