Как передать аргументы скрипта bash в подоболочку

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

#!/bin/bash
# ...
other_tool -a -b "[email protected]"

Это отлично работает, если только «другой инструмент» не запущен в подоболочке:

#!/bin/bash
# ...
bash -c "other_tool -a -b [email protected]"

Если я вызову свой сценарий оболочки следующим образом:

wrapper.sh -x "blah blup"

, тогда только первый оригинальный аргумент (-x) передается «other_tool». На самом деле я не создаю подоболочку, но передаю исходные аргументы оболочке на телефоне Android, что не должно иметь никакого значения:

#!/bin/bash
# ...
adb sh -c "other_tool -a -b [email protected]"
9 голосов | спросил Ralf Holly 21 MarpmWed, 21 Mar 2012 18:56:13 +04002012-03-21T18:56:13+04:0006 2012, 18:56:13

4 ответа


12

У команды Bash printf есть функция, которая будет указывать /escape /любую строку, так что как родительский, так и подоболочный на самом деле bash, это должно работать:

#!/bin/bash

quoted_args="$(printf " %q" "[email protected]")" # Note: this will have a leading space before the first arg
# echo "Quoted args:$quoted_args" # Uncomment this to see what it's doing
bash -c "other_tool -a -b$quoted_args"

Обратите внимание, что вы также можете сделать это в одной строке: bash -c "other_tool -a -b$(printf " %q" "[email protected]")"

ответил Gordon Davisson 22 MaramThu, 22 Mar 2012 00:02:09 +04002012-03-22T00:02:09+04:0012 2012, 00:02:09
3

Измените [email protected] на $*. Я сделал небольшой локальный тест, и он работает в моем случае.

#!/bin/sh
bash -c "echo $*"
bash -c "echo [email protected]"

Сохранение как test.sh и создание его исполняемого файла дает

$ ./test.sh foo bar
foo bar
foo

Существует тонкая разница между $* и [email protected], как вы можете видеть. См. http://ss64.com/bash/syntax-parameters.html


Для последующего вопроса в комментариях: вам нужно убежать, например. white-space "дважды", чтобы передать строку с разделителем в качестве объединенного аргумента, например. с помощью test.sh, измененного в оболочку wc:

#!/bin/sh
bash -c "wc $*"

Это работает:

$ touch test\ file
$ ./test.sh -l "test\ file"
0 test file

а

$ ./test.sh -l "test file"
wc: test: No such file or directory
wc: file: No such file or directory
0 total
ответил Daniel Andersson 21 MarpmWed, 21 Mar 2012 19:02:39 +04002012-03-21T19:02:39+04:0007 2012, 19:02:39
2

Это неудачно, потому что вы принудительно вводите массив (позиционные параметры) в строку. "[email protected]" является магическим, потому что он дает вам каждый отдельный параметр как правильно процитированную строку. Добавление дополнительного текста нарушает магию: "blah [email protected]" - это всего лишь одна строка.

Это может приблизиться к вам:

cmd="other_tool -a -b"
for parm in "[email protected]"; do cmd+=" '$parm'"; done
adb sh -c "$cmd"

Конечно, любой параметр, содержащий одну кавычку, может вызвать проблемы.

ответил glenn jackman 21 MarpmWed, 21 Mar 2012 19:47:36 +04002012-03-21T19:47:36+04:0007 2012, 19:47:36
-1
#! /bin/bash
sh -c 'other_tool -a -b "[email protected]"' -- "[email protected]"
ответил Jerry 9 Mayam15 2015, 08:42:30

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132