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

공백을 포함하는 문자열을 내 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의 함수에 공백이있는 문자열을 단일 인수로 전달하는 방법이 있습니까?



답변

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

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

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


답변

위의 문제에 대한 또 다른 해결책은 각 문자열을 변수로 설정하고 리터럴 달러 기호로 표시된 변수로 함수를 호출하는 것입니다 \$. 그런 다음 함수 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


답변

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

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


답변

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

myFunction()
{
    # same as before
}

또는:

function myFunction
{
    # same as before
}

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


답변

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

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


답변

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

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

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


답변

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

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