한 번의 호출에서 행을 인수로 사용(xargs와 유사)

한 번의 호출에서 행을 인수로 사용(xargs와 유사)

몇 줄을 인쇄하는 함수가 있는데 이를 다른 함수의 인수로 사용하고 싶습니다.

lsx() {
    echo 1 is one
    echo 2 are two
}

somefun() {
    for arg in "$@"; do
        echo "arg='$arg'"
    done
}

somefun()from 라인을 lsx()매개변수로 사용하여 어떻게 "우아하게" 전화를 걸 수 있나요 ?

지금 내가 하고 있는 일은 루프를 사용하여 행을 반복하고 while행을 배열에 저장하는 것입니다. 그러나 이것은 보기에도 좋지 않고 너무 효율적입니다. (편집: while+subshell로 인해 작동하지 않습니다). 나는 간단한(또는 심지어 이식 가능한?) 방법이 있어야 한다고 생각하지만, 하나도 알아낼 수 없습니다.

( 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)

관련 정보