2009-12-30 2 views
107

Я пишу сценарий 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?

+0

работает для меня ... Я использую полный синтаксис для функций, хотя» функции бла () {echo $ 1; } ", не может сделать короткий в один лайнер. Не уверен, что это имеет значение. Какая версия bash? – Eugene

+3

попробуйте' echo '$ @ "или' for i в "$ @"; do echo $ i; done' для использования правильно цитируемых параметров, содержащих пробелы. Это очень четко указано во всей документации 'bash' в разделе' positional parameters'. – Samveen

+1

У меня была аналогичная проблема, пытаясь передать одну кавычку в качестве параметра и только первый слово строки, которое распознается как часть параметра. Предложение Самвеена изменить от $ 1 до $ @ работало для меня. Обратите внимание, что я передавал только один параметр функции, но если бы я проходил больше, используя оператор for, были необходимы. –

ответ

116

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

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

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

+1

Это тоже очень хорошо для меня. мы вызываем другую функцию внутри myFu затем передайте аргументы с кавычками. Cheers :) – minhas23

+1

Можете ли вы объяснить, почему нужны котировки? Я пробовал как с, так и без, и это не сработало для меня. Я использую Ubuntu 14.04, GNU bash, версия 4.3.11 (1) -release (x86_64-pc-linux-gnu). Что * * работает для меня, использует $ @ (с кавычками или без них). –

4

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

myFunction() 
{ 
    # same as before 
} 

или:

function myFunction 
{ 
    # same as before 
} 

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

-2

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

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

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

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

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

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

+0

Правильный ответ: '' $ @ "', а не все цитируемые '' $ 1 "', '" $ 2 "', ... позиционные параметры или '$ *'. – Samveen

0

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

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

«переменные $»: текущий трек CDE на DEF АВСА

переменные $:

+0

OP использовал 'myFunction 'firstString" "вторую строку с пробелами" "thirdString", и это не сработало для него.Так что вы предлагаете не относится к этому вопросу. – doubleDown

14

Другим решением вышеуказанной проблемы является, чтобы установить каждую строку в переменном, вызов функция с переменными, обозначаемая буквенным знаком доллара \$. Затем в функции используйте 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 мышления мои переменные пространства delimeted. Я пытался передать строку с разделителем на строку с помощью функции awk, чтобы установить серию переменных, которые позже используются для создания отчета. Сначала я попробовал решение, отправленное ghostdog74, но не смог заставить его работать, поскольку не все мои параметры передавались в кавычках. После добавления двойных кавычек к каждому параметру он начал функционировать должным образом.

Ниже приведено состояние моего кода и полностью функционирует после состояния.

Before - Non Функционирование Кодекса

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

Простое решение, которое работает для меня, - цитирует $ @

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

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

0

Самое простое решение этой проблемы заключается в том, что вам просто нужно использовать \ «для космических отделено заданы параметры при запуске оболочки сценарий #!/bin/bash myFunction { echo $1 echo $2 echo $3 } myFunction "firstString" "\"Hello World\"" "thirdString"

Смежные вопросы