Подтвердить что ты не робот

Bash: объединить все аргументы и обернуть их двойными кавычками

function foo() {
[email protected]
echo $A
}

foo bla "hello ppl"

Я хотел бы, чтобы результат был:
" bla "" hello ppl"

Что мне нужно сделать вместо эллипса?

4b9b3361

Ответ 1

@msw имеет правильную идею (в комментариях к вопросу). Однако другая идея печатать аргументы с кавычками: используйте неявную итерацию printf:

foo() { printf '"%s" ' "[email protected]"; echo ""; }

foo bla "hello ppl"
# => "bla" "hello ppl"

Ответ 2

Используйте подстановку параметров для добавления "в качестве префикса и суффикса:

function foo() {
    A=("${@/#/\"}")
    A=("${A[@]/%/\"}")
    echo -e "${A[@]}"
}

foo bla "hello ppl" kkk 'ss ss'

Выход

"bla" "hello ppl" "kkk" "ss ss"

Ответ 3

Вы можете использовать "$ @" для обработки каждого параметра как, ну, отдельный параметр, а затем цикл по каждому параметру:

function foo() {
for i in "[email protected]"
do
    echo -n \"$i\"" "
done
echo
}

foo bla "hello ppl"

Ответ 4

ninjalj имел правильную идею, но использование кавычек было нечетным, отчасти потому, что то, о чем спрашивает OP, на самом деле не самый лучший выходной формат для многих задач оболочки. На самом деле, я не могу понять, что это за цель, но:

function quote_args {
   for i ; do
      echo \""$i"\"
   done
}

помещает свои цитированные аргументы по одной строке, что обычно является наилучшим способом подачи других программ. Вы получаете результат в форме, которую вы не запрашивали:

$ quote_args this is\ a "test really"
"this"
"is a"
"test really"

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

$ echo `quote_args this is\ a "test really"`
"this" "is a" "test really"

но если он не пройдет через другой проход eval, дополнительные кавычки, вероятно, повредят. То есть ls "is a file" будет отображать файл is a file, а

$ ls `quote_args is\ a\ file`

попытается перечислить "is, a и file", которые вы, вероятно, не хотите.

Ответ 5

Никакой цикл не требуется:

foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; }

Сохранение IFS не требуется в этом простом примере, особенно для его восстановления до выхода функции из-за того, что используется local. Тем не менее, я включил его в том случае, если другие функции входят в функцию, которая может повлиять на измененный IFS.

Пример выполнения:

$ foo a bcd "efg hij" k "lll mmm nnn " ooo "   ppp   qqq   " rrr\ sss
 "a" "bcd" "efg hij" "k" "lll mmm nnn " "ooo" "   ppp   qqq   " "rrr sss"

Ответ 6

Единственное решение в это время, которое учитывает обратные косые черты и кавычки внутри аргумента:

$ concatenate() { printf "%q"" " "[email protected]"; echo ""; }
$ concatenate arg1 "arg2" "weird arg3\\\\\\bbut\" legal!"
arg1 arg2 weird\ arg3\\\\\\bbut\"\ legal\!

Обратите внимание на "% q" ""

% q ARGUMENT печатается в формате, который может быть повторно использован как оболочка вход, экранирование непечатаемых символов с помощью               предложенный синтаксис POSIX $'.

Специальные символы (\, \b backspace,...) действительно будут интерпретироваться принимающей программой, даже если они не отображаются в терминальном выводе.

Пусть тест:

# display.sh: Basic script to display the first 3 arguments passed
echo -e '#!/bin/bash'"\n"'echo -e "\$1=""$1"; echo -e "\$2=""$2"; echo -e "\$3=""$3"; sleep 2;' > display.sh
sudo chmod 755 display.sh

# Function to concatenate arguments as $ARGS
# and "evalutate" the command display.sh $ARGS
test_bash() { ARGS=$(concatenate "[email protected]"); bash -c "./display.sh ""$ARGS"; }

# Test: Output is identical whatever the special characters
./display.sh arg1 arg2 arg3
test_bash    arg1 arg2 arg3

Более сложный тест:

./display.sh arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
test_bash    arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"

В display.sh мы используем echo -e вместо echo или printf для интерпретации специальных символов. Это только представитель, если ваша вызываемая программа интерпретирует их.

-e позволяет интерпретировать escape-обратные сбрасывания

Если -e действует, распознаются следующие последовательности:

  • \backslash
  • \a alert (BEL)
  • \b backspace
  • Etc.

NB: \b является символом обратного пробела, поэтому он стирает Y в примере.

Обратите внимание, что этот пример не должен воспроизводиться в реальном коде:

Благодаря принятому ответу и Danny Hong answer в разделе "Как избежать двойной цитаты внутри двойной кавычки?"