function foo() {
[email protected]
echo $A
}
foo bla "hello ppl"
Я хотел бы, чтобы результат был:
" bla "" hello ppl"
Что мне нужно сделать вместо эллипса?
function foo() {
[email protected]
echo $A
}
foo bla "hello ppl"
Я хотел бы, чтобы результат был:
" bla "" hello ppl"
Что мне нужно сделать вместо эллипса?
@msw имеет правильную идею (в комментариях к вопросу). Однако другая идея печатать аргументы с кавычками: используйте неявную итерацию printf
:
foo() { printf '"%s" ' "[email protected]"; echo ""; }
foo bla "hello ppl"
# => "bla" "hello ppl"
Используйте подстановку параметров для добавления "в качестве префикса и суффикса:
function foo() {
A=("${@/#/\"}")
A=("${A[@]/%/\"}")
echo -e "${A[@]}"
}
foo bla "hello ppl" kkk 'ss ss'
Выход
"bla" "hello ppl" "kkk" "ss ss"
Вы можете использовать "$ @" для обработки каждого параметра как, ну, отдельный параметр, а затем цикл по каждому параметру:
function foo() {
for i in "[email protected]"
do
echo -n \"$i\"" "
done
echo
}
foo bla "hello ppl"
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"
, которые вы, вероятно, не хотите.
Никакой цикл не требуется:
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"
Единственное решение в это время, которое учитывает обратные косые черты и кавычки внутри аргумента:
$ 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 в примере.
Обратите внимание, что этот пример не должен воспроизводиться в реальном коде:
bash -c
и screen -X
DO принимают несколько аргументов, поэтому нет необходимости использовать конкатенацию: см. Невозможно использовать параметр bash -c с аргументами после - c строка опций). Просто остерегайтесь передавать что-то для $0
при использовании bash -c
.Благодаря принятому ответу и Danny Hong answer в разделе "Как избежать двойной цитаты внутри двойной кавычки?"