На самом деле ответ @ Graeme - и ваш вопрос - просто ссылаются на побочные эффекты того, как обрабатывает оболочка. "$@positional $*parameters".
Они назначаются оболочкой своим аргументам при вызове и в любое время позже с помощью встроенной set
утилиты. Они могут быть вызваны в любое время с помощью либо того, "$*"
который разделяет каждый позиционный элемент с первым символом, "$IFS"
либо "$@"
который цитирует каждый позиционный элемент и разделяет их со всеми"$IFS."
man set
NAME
set — set or unset options and positional parameters
SYNOPSIS
set [−abCefhmnuvx] [−o option] [argument...]
set [+abCefhmnuvx] [+o option] [argument...]
set −− [argument...]
set −o
set +o
Если у вас уже есть значения, которые вы вводите в оболочку, вам не нужно делать это --
три раза. Параметры оболочки могут set
- всегда, в любое время, а не только при вызове (исключая $ 0 и -i):
su - mikeserv -c 'set -- "$*" ; echo "$*" ;
set -- 4 5 6 ; echo "$*"' -- -- 7 8 9
7 8 9
4 5 6
И все эти цитаты из оболочки могут сбивать с толку. Это немного упрощает вещи:
( set -- 4 5 6
su - mikeserv 4<<-\CMD /dev/fd/4 "$@"
echo $0 "$*"
set -- "$*"
echo "$*"
set -- 7 8 9
echo "$*"
CMD
)
/dev/fd/4 4 5 6
4 5 6
7 8 9
Аргументы родительской оболочки равны 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}
файл непосредственно из командной строки, выполните:
su -c '. /dev/fd/'${num} ${num}<<SCRIPT
Использование двух heredocs может помочь с побегом. Вот что происходит в каждом случае:
НЕТ УСТАНОВЛЕНО <<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'without set "$@" or \$@ in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ВЫВОД
without set "$@" or \$@ in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' $@ "$@"
PREQUOTED
/dev/fd/5
'' $@ "$@" $@
\$@ $@ "\$@"
SET "$@"
IN<<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'set "$@" and \$@ in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
set -- "$@" "\$@"
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
set -- "$@" "\$@"
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ВЫВОД
set "$@" and \$@ in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' 1 2 3 4 5 6 $@ 1 2 3 4 5 6
"$@"
PREQUOTED
/dev/fd/5 1 2 3 4 5 6 $@
'1 2 3 4
5 6' '$@' 1 2 3 4 5 6
$@ $@ 1 2 3 4 5 6 $@
"$@" $@ \$@ $@
"\$@"
УСТАНОВИТЬ "$@"
И БОЛЬШЕ В<<HEREDOC
sh 3<<\CMD /dev/fd/3
( echo 'set "$@" and \$@ AND additional parameters in here-doc' ; echo
set -- '1 "2" 3' 4 "5 6"
su - mikeserv 4<<-UNQUOTED 5<<-\PREQUOTED /dev/fd/4
set -- "$@" "\$@" '7 "8" 9' 10 "11 12"
echo UNQUOTED; echo $0 "$*"
printf "%s\\t\\t%s\\t\\t%s\\t\\t%s\\n" $(printf "'%s' " "$@") \\
$@ '$@' "$@" '"$@"' "'$@'" \$@ '\$@' "\$@" '"\$@"'
. /dev/fd/5
UNQUOTED
set -- "$@" "\$@" '13 "14" 15' 16 "17 18"
echo PREQUOTED ; echo $0 "$*"
printf "%s\t\t%s\t\t%s\t\t%s\n" $(printf "'%s' " "$@") \
$@ '$@' "$@" '"$@"' \$@ '\$@' "\$@" '"\$@"'
PREQUOTED
)
CMD
ВЫВОД
set "$@" and \$@ AND additional parameters in here-doc
UNQUOTED
/dev/fd/3 1 2 3 4 5 6
1 "2" 3 4 5 6 1
2 3 4 5
6 1 "2" 3 4 5 6 1 2 3 4 5 6 "1 "2" 3 4 5 6"
'1 2 3 4 5 6' 1 2 3 4 5 6 7 "8" 9 10
11 12 $@ 1 2 3 4 5 6 7 "8" 9
10 11 12 "$@"
PREQUOTED
/dev/fd/5 1 2 3 4 5 6 7 "8" 9 10 11 12 $@ 13 "14" 15 16 17 18
'1 2 3 4
5 6' '7 "8"
9' '10' '11 12'
'$@' '13 "14" 15'
'16' '17 18' 1 2 3 4 5 6
7 "8" 9 10 11 12 $@
13 "14" 15 16 17 18 $@
1 2 3 4 5 6 7 "8" 9 10 11 12
$@ 13 "14" 15 16 17 18
"$@" $@ \$@ $@
"\$@"
bash 4.2.45
как на исходном, так и на конечном счете.