bash에서 공백이있는 문자열을 함수 인수로 전달


173

공백을 포함하는 문자열을 내 bash 스크립트의 함수에 전달 해야하는 bash 스크립트를 작성 중입니다.

예를 들면 다음과 같습니다.

#!/bin/bash

myFunction
{
    echo $1
    echo $2
    echo $3
}

myFunction "firstString" "second string with spaces" "thirdString"

실행할 때 예상되는 결과는 다음과 같습니다.

firstString
second string with spaces
thirdString

그러나 실제로 출력되는 것은 다음과 같습니다.

firstString
second
string

bash의 함수에 공백이있는 문자열을 단일 인수로 전달하는 방법이 있습니까?


나를 위해 작동 ... "함수 bla () {echo $ 1;}",하지만 하나의 라이너로 짧게 만들 수 없지만 함수에 대한 전체 구문을 사용합니다. 차이가 있는지 확실하지 않습니다. bash의 버전은 무엇입니까?
Eugene

8
시도 echo "$@"또는 for i in "$@"; do echo $i ; done공백이 포함 된 올바르게 인용 매개 변수를 사용합니다. 이것은 섹션의 모든 bash문서 에서 매우 명확하게 언급됩니다 positional parameters.
Samveen

1
비슷한 문제가 발생하여 인용 된 문자열을 매개 변수로 전달하고 문자열의 첫 단어 만 매개 변수의 일부로 인식하려고했습니다. $ 1에서 $ @로 바꾸 겠다는 Samveen의 제안이 저에게 효과적이었습니다. 함수에 하나의 매개 변수 만 전달했지만 for 문을 사용하여 더 많은 매개 변수를 전달한 경우 필요했습니다.
Erin Geyer


1
시도 myFunction "$@"
vimjet

답변:


176

따옴표를 넣어야하며 함수 선언이 잘못되었습니다.

myFunction()
{
    echo "$1"
    echo "$2"
    echo "$3"
}

그리고 다른 사람들처럼, 그것은 나에게도 효과적입니다. 사용중인 쉘의 버전을 알려주십시오.


3
이것은 나에게도 잘 작동합니다. myFunction 내부에서 다른 함수를 호출하는 경우 따옴표로 인수를 전달하십시오. 건배 :)
minhas23

2
왜 따옴표가 필요한지 설명 할 수 있습니까? 나는 유무에 관계없이 시도했지만 그것은 효과가 없었습니다. Ubuntu 14.04, GNU bash, 버전 4.3.11 (1)-릴리스 (x86_64-pc-linux-gnu)를 사용하고 있습니다. 무엇 않는 나를 위해 일하면 $를 사용하고 @ (또는 따옴표없이).
Kyle Baker

@KyleBaker는 따옴표없이 $@인용 부호처럼 동작 합니다. $*결과는 문자열 분리 된 후 개별적으로 확장됩니다. 따라서 탭이 있으면 공백으로 변환됩니다. 등이 될 것입니다
찰스 더피

17

위의 문제에 대한 또 다른 해결책은 각 문자열을 변수로 설정하고 리터럴 달러 기호로 표시된 변수로 함수를 호출하는 것입니다 \$. 그런 다음 함수 eval에서 변수를 읽고 예상대로 출력합니다.

#!/usr/bin/ksh

myFunction()
{
  eval string1="$1"
  eval string2="$2"
  eval string3="$3"

  echo "string1 = ${string1}"
  echo "string2 = ${string2}"
  echo "string3 = ${string3}"
}

var1="firstString"
var2="second string with spaces"
var3="thirdString"

myFunction "\${var1}" "\${var2}" "\${var3}"

exit 0

출력은 다음과 같습니다.

    string1 = firstString
    string2 = second string with spaces
    string3 = thirdString

이와 비슷한 문제를 해결하기 위해 유닉스 문제가 발생하여 변수가 공간을 차지한다고 생각했습니다. awk나중에 보고서를 만드는 데 사용되는 일련의 변수를 설정하는 데 사용 하는 파이프 구분 문자열을 함수에 전달하려고했습니다 . 처음에는 ghostdog74에 의해 게시 된 솔루션을 시도했지만 모든 매개 변수가 따옴표로 전달되지는 않았으므로 작동하지 못했습니다. 각 매개 변수에 큰 따옴표를 추가 한 후 예상대로 작동하기 시작했습니다.

아래는 내 코드의 이전 상태이며 완전한 상태 이후 기능입니다.

이전-작동하지 않는 코드

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Error Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Does Not Work Since There Are Not Quotes Around The 3
  iputId=$(getField "${var1}" 3)
done<${someFile}

exit 0

후-기능 코드

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Now Works As There Are Quotes Around The 3
  iputId=$(getField "${var1}" "3")
done<${someFile}

exit 0

7

이 문제에 대한 가장 간단한 해결책 \"은 쉘 스크립트를 실행할 때 공백으로 구분 된 인수 에만 사용해야한다는 것 입니다.

#!/bin/bash
myFunction() {
  echo $1
  echo $2
  echo $3
}
myFunction "firstString" "\"Hello World\"" "thirdString"

5

myFunction에 대한 정의가 잘못되었습니다. 그것은해야한다:

myFunction()
{
    # same as before
}

또는:

function myFunction
{
    # same as before
}

어쨌든, Bash 3.2.48에서 괜찮아 보이고 잘 작동합니다.


5

나는 9 년 늦었지만 더 역동적 인 방법은

function myFunction {
   for i in "$*"; do echo "$i"; done;
}

2
아 좋아! 이것은 많은 질문에서 한동안 내가 찾은 것입니다. 감사합니다!
prosoitos

2

나를 위해 일한 간단한 솔루션-인용 인용 $ @

Test(){
   set -x
   grep "$@" /etc/hosts
   set +x
}
Test -i "3 rb"
+ grep -i '3 rb' /etc/hosts

실제 grep 명령을 확인할 수 있습니다 (-x 설정 덕분에).


-1

초기 텍스트가 문자열 유형 변수로 설정된 경우이 문제를 확장 할 수 있습니다. 예를 들면 다음과 같습니다.

function status(){    
  if [ $1 != "stopped" ]; then
     artist="ABC";
     track="CDE";
     album="DEF";
     status_message="The current track is $track at $album by $artist";
     echo $status_message;
     read_status $1 "$status_message";
  fi
}

function read_status(){
  if [ $1 != "playing" ]; then
    echo $2
  fi
}

이 경우 status_message 변수를 문자열 ( ""로 묶음)로 전달하지 않으면 다른 인수로 분할됩니다.

"$ variable" : 현재 트랙은 ABC의 DEF에서 CDE입니다.

$ variable : The


OP가 사용되었지만 myFunction "firstString" "second string with spaces" "thirdString"그에게 효과가 없었습니다. 따라서 제안한 내용은이 질문에 적용되지 않습니다.
doubleDown

-2

같은 종류의 문제가 있었으며 실제로 문제는 함수 나 함수 호출이 아니라 함수에 인수로 전달한 것입니다.

이 함수는 스크립트 본문- 'main'에서 호출되었으므로 명령 행에서 "st1 a b" "st2 c d" "st3 e f"를 전달하고 myFunction $ *를 사용하여 함수에 전달했습니다.

$ *는 공백 문자를 구분 기호로 사용하여 함수를 호출 할 때 해석되는 문자 세트로 확장 될 때 문제가 발생합니다.

해결책은 명시 적 인수 처리에서 함수에 대한 호출을 '메인'에서 함수로 변경하는 것입니다. 호출은 myFunction "$ 1" "$ 2" "$ 3"이되어 따옴표가 구분되므로 문자열 내부의 공백이 보존됩니다. 인수 ... 따라서 매개 변수에 공백이 포함될 수 있으면 모든 함수 호출에서 명시 적으로 처리해야합니다.

이것이 문제에 대한 긴 검색의 이유 일 수 있으므로 $ *를 사용하여 인수를 전달하지 않는 것이 좋습니다.

이것이 언젠가 누군가를 도울 수 있기를 바랍니다 ... Jan.


정답은 "$@"모든 인용 "$1", "$2"... 위치 paramters 아니다 $*.
Samveen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.