Передача строки с пробелами в качестве аргумента функции в bash

Я пишу bash script, где мне нужно передать строку, содержащую пробелы, функции в моем bash script.

Например:

#!/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?

Ответ 1

вы должны поставить кавычки, а также, ваше объявление функции неверно.

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

И, как и другие, он работает и для меня. Скажите нам, какую версию оболочки вы используете.

Ответ 2

Еще одно решение проблемы выше - установить каждую строку в переменную, вызвать функцию с переменными, обозначенными буквенным знаком доллара \$. Затем в функции используйте 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

Пытаясь решить подобную проблему, я столкнулся с проблемой UNIX, считая, что мои переменные были разделены пробелами. Я пытался передать строку с разделителем на строку с помощью функции 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

Ответ 3

Простейшее решение этой проблемы заключается в том, что вам нужно просто использовать \" для аргументов, разделенных пробелами, при запуске сценария оболочки:

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

Ответ 4

Ваше определение myFunction неверно. Это должно быть:

myFunction()
{
    # same as before
}

или

function myFunction
{
    # same as before
}

В любом случае, он выглядит отлично и отлично работает для меня на Bash 3.2.48.

Ответ 5

Простое решение, которое сработало для меня - цитировало [email protected]

Test(){
   set -x
   grep "[email protected]" /etc/hosts
   set +x
}
Test -i "3 rb"
+ grep -i '3 rb' /etc/hosts

Я могу проверить фактическую команду grep (благодаря набору -x).

Ответ 6

Я опоздал на 9 лет, но более динамичный путь был бы

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

Ответ 7

У вас может быть расширение этой проблемы в случае, если ваш исходный текст был установлен в переменную типа строки, например:

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 forward в качестве строки (в окружении ""), она будет разделена на монтирование различных аргументов.

"$ variable" : Текущая дорожка - это CDE в DEF по ABC

$variable:

Ответ 8

Имел такую ​​же проблему, и на самом деле проблема заключалась не в функции, а в вызове функции, а в том, что я передал в качестве аргументов функции.

Функция вызывается из тела script - "main" - поэтому я передал "st1 ab" "st2 cd" "st3 ef" из командной строки и передал ее функции, используя myFunction $*

Проблема $* вызывает проблему, так как она расширяется до набора символов, которые будут интерпретироваться при вызове функции с использованием пробела в качестве разделителя.

Решение заключалось в том, чтобы изменить вызов функции при явной обработке аргументов от "main" к функции: тогда вызов будет myFunction "$ 1" "$ 2" "$ 3", который сохранит пробелы внутри строк, как цитаты разделит аргументы... Поэтому, если параметр может содержать пробелы, он должен обрабатываться явно во всех вызовах функций.

Поскольку это может быть причиной длительных поисков проблем, может быть разумным никогда не использовать $* для передачи аргументов...

Надеюсь, это поможет кому-то, когда-нибудь, где-нибудь... Январе