Я не могу использовать параметр Bash "-c" с аргументами после строки параметра "-c" - PullRequest
27 голосов
/ 11 ноября 2009

В справочной странице Bash говорится о опции -c:

-c <i>string</i> Если опция -c присутствует, то команды читаются из string. Если есть аргументы после строка, они назначены позиционные параметры, начиная с $0.

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

bash -c "echo arg 0: $0, arg 1: $1" arg1

но выходные данные просто показывают следующее, поэтому похоже, что аргументы после строки -c не присваиваются позиционным параметрам.

arg 0: -bash, arg 1:

Я использую довольно древнюю версию Bash (на Fedora 4):

[root @ dd42 trunk] # bash --version GNU bash, версия 3.00.16 (1) -релиз (i386-redhat-linux-gnu) Copyright (C) 2004 Free Software Foundation, Inc.

Я действительно пытаюсь выполнить небольшой сценарий оболочки с аргументами. Я думал, что -c выглядит очень многообещающе, поэтому проблема выше. Мне было интересно использовать eval, но я не думаю, что смогу передать аргументы тому, что следует за eval. Я открыт и для других предложений.

Ответы [ 4 ]

34 голосов
/ 11 ноября 2009

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

$ bash -c 'echo arg 0: $0, arg 1: $1' arg1 arg2
arg 0: arg1, arg 1: arg2

Или экранируйте переменные в вашей строке в двойных кавычках. То, что использовать, может зависеть от того, что именно вы хотите вставить в свой фрагмент кода.

4 голосов
/ 11 ноября 2009

Потому что '$0' и '$1' в вашей строке заменены на переменные # 0 и # 1 соответственно.

Попробуйте:

bash -c "echo arg 0: \$0, arg 1: \$1" arg0 arg1

В этом коде $ обоих - escape, поэтому base воспринимает это как строку $ и не заменяется.

Результат этой команды:

arg 0: arg0, arg 1: arg1

Надеюсь, это поможет.

2 голосов
/ 18 сентября 2014

Мартин прав насчет интерполяции: вам нужно использовать одинарные кавычки. Но учтите, что если вы пытаетесь передать аргументы команде, которая выполняется внутри строки, вам необходимо явно переслать их. Например, если у вас есть скрипт foo.sh вроде:

#!/bin/bash
echo 0:$0
echo 1:$1
echo 2:$2

Тогда вы должны назвать это так :

$ bash -c './foo.sh ${1+"$@"}' foo "bar baz"
0:./foo.sh
1:bar baz
2:

Или, в более общем смысле, bash -c '${0} ${1+"$@"}' <command> [argument]...

Не так :

$ bash -c ./foo.sh foo "bar baz"
0:./foo.sh
1:
2:

Не так :

$ bash -c './foo.sh $@' foo "bar baz"
0:./foo.sh
1:bar
2:baz

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

2 голосов
/ 11 ноября 2009

Добавьте обратную косую черту к $0 (то есть, \$0), в противном случае ваша текущая оболочка экранируется $0 с именем оболочки еще до того, как она попадет в подоболочку.

...