위치 매개변수를 보유하는 파이프에서 읽는 방법은 무엇입니까?

위치 매개변수를 보유하는 파이프에서 읽는 방법은 무엇입니까?

저는 작은 스크립트를 작성 중인데 파이프된 입력 또는 명령줄 인수를 통해 실행하고 싶습니다.

my_function() {
  for i in "$@"; do
    echo "$i"
    echo -----
  done
}

if [ -t 0 ]; then
  my_function "$@"    # command-line arguments
else
  my_function $(cat)  # pipe
fi

다음 옵션이 유효합니다.

$ my_script 1 2 3 4
$ echo 1 2 3 4 | my_script
1
-----
2
-----
3
-----
4
-----

이것도 잘 작동합니다:

$ my_script 1 "2 3" 4
1
-----
2 3
-----
4
-----

파이프라인에서 위치 매개변수를 보존하려고 할 때 문제가 발생합니다.

$ echo 1 "2 3" 4 | my_script
1
-----
2
-----
3
-----
4
-----

$ echo 1 "'2 3'" 4 | my_script
1
-----
'2
-----
3'
-----
4
-----

대신 좋은 결과 없이 my_function $(cat)사용해 보았습니다 . 예를 들면 다음과 같습니다.read

read input
my_function $input

이것에 대한 생각이 있나요? 나는 단어 분할이 어렵다는 것을 안다.

답변1

bash 4.4를 사용하여 이 기술을 살펴보겠습니다.

function myf { 
  if ! [ -t 0 ];then 
    declare -a args=\($(</dev/stdin)\);
    set -- "${args[@]}"; 
  fi;
  for i in "$@";do 
    echo "$i";
    echo -----;
  done 
}

시험:

$ function myf { if ! [ -t 0 ];then declare -a args=\($(</dev/stdin)\);set -- "${args[@]}"; fi;for i in "$@";do echo "$i";echo -----;done }
$ myf 1 "2 3" 4
1
-----
2 3
-----
4
-----

$ echo $'1 "2 3" 4'|myf
1
-----
2 3
-----
4
-----

다음을 사용하여 동일한 결과를 얻을 수 있습니다.

$ echo 1 \"2 3\" 4 |myf
$ echo 1 "'2 3'" 4 |myf

하지만 echo 1 "2 3" 4bash는 이 구문에서 큰따옴표를 무시하기 때문에 작동하지 않습니다.

$ echo 1 "2 3" 4
1 2 3 4

관련 정보