Ограничение аргумента Linux 2 -(интерпретатор + один аргумент )отмечено в большинстве ответов,но говорить, что это невозможно сделать, неверно — нужно просто перейти на интерпретатор, который может сделать что-то полезное с одним аргументом:
#!/usr/bin/perl -we%ENV=();exec "/bin/sh ". join " ", map "'$_'", @ARGV;
# your sh script here
Это вызывает perl
с одним -лайнером (-e
), который очищает%ENV
(дешевле, чем env -i
), и вызывает exec /bin/sh
, правильно цитируя аргументы. При необходимости можно добавить дополнительную perl
логику (, хотя в Linux это не так много, поскольку вы ограничены BINPRM_BUF_SIZE
символами, что, вероятно, составляет 128)
К сожалению, это специфично для Linux, оно не будет работать в системе, допускающей несколько аргументов шебанга :-/
perl
обрабатывает эту строку как один аргумент, поэтому она не заключена в кавычки выше, как вы обычно делаете с perl -e...
из командной строки (, если вы добавляете кавычки, они сохраняются, perl видит только литеральная строка с предупреждениями будет жаловаться на бесполезную константу ).
Также обратите внимание, что при таком использовании поведение немного меняется: @ARGV
обычно содержит только аргументы, а $0
содержит скрипт, но с этим шебангом $ARGV[0]
является именем скрипта (и $0
это -e
), что немного упрощает задачу.
Вы также можете решить эту проблему с помощью интерпретатора, который "повторно обрабатывает" свою командную строку (без дополнительного -c
аргумента )древняя AT&T ksh93
делает:
#!/bin/ksh /usr/bin/env -i /bin/sh
хотя, возможно, ksh
в наши дни встречается не так часто;-)
(bash
имеет аналогичную функцию с --wordexp
, , но он «недокументирован» в версиях, где он работает, и не включается во время компиляции в версиях, где он задокументирован :-/ Он также может не может использоваться для этого, так как ему нужны два аргумента...)
Кроме того, фактически вариант ответов @Patrick и @maxschlepzig:
#!/bin/bash
[ "$_" != bash ] && exec -c -a "bash" /bin/bash "$0" "$@"
# your script here
Вместо использования новой переменной используется специальная переменная " _
",если он не установлен точно на «bash», замените сценарий на exec
, используя -a
, чтобы сделатьARGV[0]
(и, следовательно,$_
)просто «bash», и используя -c
, чтобы очистить среду.
В качестве альтернативы, если допустимо очищать среду в начале скрипта (только bash):
#!/bin/sh
unset $(compgen -e)
# your script here
При этом используетсяcompgen
(помощник завершения )для вывода списка имен всех экспортируемых переменных среды и unset
для их обработки за один раз.
См. также Множественные аргументы в шебанге для более подробной информации об общей проблеме поведения шебанга.
Как вы можете прочитать на справочной странице Debian для демона , это сильно зависит от того, как вы реализовали свой демон в какой системе инициализации.
... 10.Instead of using the syslog() call to log directly to the system syslog service, a new-style daemon may choose to simply log to standard error via fprintf(), which is then forwarded to syslog by the init system...
В этом последнем случае поведение, которое вы заметили под своим xterm, является нормальным.
То, что демон выводит через fprintf (stdout / stderr ), затем контролируется системным журналом.
Таким образом, в зависимости от конфигурации вашего системного журнала (, которую вы найдете в файле syslog.conf )и в зависимости от уровня журнала, вывод вашего демона будет игнорироваться/добавляться к какому-то конкретному файлу/отображаться на системная консоль (ваш tty1 )и никогда xterm.
Это поведение приложения, а не всей системы. rsyslog будет вызываться только тогда, когда это делает приложение, через службу ведения журналов или что-то подобное. Стандартный вывод и поток ошибок, если они не перенаправлены, отображаются на вашем экране.