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

Ограничение аргумента 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для их обработки за один раз.

См. также Множественные аргументы в шебанге для более подробной информации об общей проблеме поведения шебанга.

4
26.08.2020, 12:08
2 ответа

Как вы можете прочитать на справочной странице Debian для демона , это сильно зависит от того, как вы реализовали свой демон в какой системе инициализации.

  • Способ SysV (stdin/out/err подключен к /dev/null)
  • Способ " Новый -стиль ":(stdout/stderr направлен на systemd -journald.service)

... 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.

3
18.03.2021, 23:09

Это поведение приложения, а не всей системы. rsyslog будет вызываться только тогда, когда это делает приложение, через службу ведения журналов или что-то подобное. Стандартный вывод и поток ошибок, если они не перенаправлены, отображаются на вашем экране.

0
18.03.2021, 23:09

Теги

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