man su
говорит:
You can use the -- argument to separate su options from the arguments
supplied to the shell.
man bash
говорит:
-- A -- signals the end of options and disables further option
processing. Any arguments after the -- are treated as filenames
and arguments. An argument of - is equivalent to --.
Ну что ж, посмотрим:
[root ~] su - yuri -c 'echo "$*"' -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- - 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' - 1 2 3
1 2 3
Что я ожидал (вывод второй команды отличается):
[root ~] su - yuri -c 'echo "$*"' -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- -- 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' -- - 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' - 1 2 3
1 2 3
Вероятно, не большая проблема. Но что там происходит? Второй и третий варианты кажутся подходящими, но один из них не работает. Четвертый кажется ненадежным, -
может рассматриваться как su
вариант.
bash 4.2.45
как на исходном, так и на конечном счете.Ответы:
Происходит следующее: первый аргумент, который вы указываете оболочке, - это
$0
параметр (обычно это имя оболочки). Это не входит, когда вы делаете,echo $*
так$*
как каждый аргумент кроме$0
.Пример:
Обновить
Делаем следующую команду:
дает прямую линию:
Так что почему-то кажется, что в этом случае
su
мы поглощаем лишнее,--
не передавая его bash, возможно, из-за ошибки (или, по крайней мере, недокументированного поведения). Однако это не съест больше двух--
аргументов:источник
su - yuri -c 'echo "$*"' -- -- 1 2 3
оболочка предположительно получает-- 1 2 3
, но выводит только2 3
. Это вообще имеет какой-то смысл?bash -c 'echo $*' -- 1 2 3
, это выводит,1 2 3
как ожидалось.su
ошибку.На самом деле ответ @ Graeme - и ваш вопрос - просто ссылаются на побочные эффекты того, как обрабатывает оболочка.
"$@positional $*parameters".
Они назначаются оболочкой своим аргументам при вызове и в любое время позже с помощью встроеннойset
утилиты. Они могут быть вызваны в любое время с помощью либо того,"$*"
который разделяет каждый позиционный элемент с первым символом,"$IFS"
либо"$@"
который цитирует каждый позиционный элемент и разделяет их со всеми"$IFS."
Если у вас уже есть значения, которые вы вводите в оболочку, вам не нужно делать это
--
три раза. Параметры оболочки могутset
- всегда, в любое время, а не только при вызове (исключая $ 0 и -i):И все эти цитаты из оболочки могут сбивать с толку. Это немного упрощает вещи:
Аргументы родительской оболочки равны
set
4, 5 и 6 и затем передаются в подоболочку, вызываемуюsu
через позиционныйparameter "$@array".
Обратите внимание на то, как я
( subshell )
выполняю приведенную выше команду - я делаю это, потому что я не хочу возиться с моей текущей средой оболочки - потому что я могу непреднамеренно изменить то, что я предпочел бы не делать, если бы я сделал сset.
О НАПРАВЛЕНИИ:
Прежде всего, ваша система Unix работает с файлами - разрешениями на файлы, содержимым файлов, атрибутами файлов. Так или иначе, каждый используемый вами объект данных может (и, по крайней мере, на мой взгляд, должен) рассматриваться как файл. Перенаправление указывает на файл - и все. A
<<HERE-DOCUMENT
опишет файл в строке, а затем перенаправит его. Либо расширения оболочки интерпретируются, либо нет.Аскер отмечает в комментариях ниже, что когда он пытается использовать этот метод в качестве
root
пользователя, ему выдается ошибка прав доступа. Когда я ответил , я предложил , чтобы онchown
илиchgrp
в/dev/fd/${num}
специальный файл, но это, вероятно , не лучший метод. Причиной, по которой он сталкивается с этой проблемой,root
является предоставлениеread
разрешений, но неexecute
разрешений. Вы можете легко справиться с этим, просто избегаяexec
вызова. Вместо того, чтобы вызывать/dev/fd/${num}
файл непосредственно из командной строки, выполните:Использование двух heredocs может помочь с побегом. Вот что происходит в каждом случае:
НЕТ УСТАНОВЛЕНО
<<HEREDOC
ВЫВОД
SET
"$@"
IN<<HEREDOC
ВЫВОД
УСТАНОВИТЬ
"$@"
И БОЛЬШЕ В<<HEREDOC
ВЫВОД
источник
"8 9\n4 5 6\n"
. Я бегуdebian 6
,bash-4.1.5
иsu
.root
него , говорит:-su: /dev/fd/4: Permission denied
. Кстати, вы знаете, что это значит? В противном случае он выводит, как вы говорите, но не решает вопрос. Вопрос об использовании--
и-
.chown /dev/fd/4
это делать на время, или простоchgrp
. У меня не так много времени для тестирования прямо сейчас. Но это немного не относится к делу, как и в случае с другими, вам вообще не нужно передавать аргументы в конце - просто поработайте над цитатой. Видишь это сейчас?su
невозможностью работать с перенаправленнымstdin
, передача аргументов еще лучше, чем внедрение их в команду. Потому что в последнем случае вам нужно избежать их.