Следующее должно работать вsh
:
"$@" 2>&1 | while read line ; do echo -e "r2g: $line" ; done
Обратите внимание, что поведение echo -e
может отличаться в sh (, например. на самом деле он может вывести -e r2g:...
.)
Слишком длинный список аргументов — это сообщение об ошибке, которое обычно соответствует коду ошибки E2BIG :
.$ zmodload zsh/system
$ syserror E2BIG
Argument list too long
E2BIG — это код ошибки, возвращаемый execve()
при запросе на выполнение команды со списком аргументов и строк переменных среды, превышающих поддерживаемые, или в Linux, когда размер одного аргумента или строки переменных среды превышает 128 КБ.
Общий предел и способ расчета размера зависят от системы. В современных версиях Linux это производное от текущего ограничения размера стека. Вы можете получить его с помощью getconf ARG_MAX
(, если вы можете выполнитьgetconf
):
$ getconf ARG_MAX
2097152
$ limit stacksize 1024 # KiB, so 1MiB
$ getconf ARG_MAX
262144
Это четверть ограничения на размер стека, хотя он составляет не менее 128 КБ (, и если вы уменьшите ограничение на размер стека слишком низко, вы начнете сталкиваться со всевозможными другими проблемами ).
Здесь, поскольку вы получаете сообщение об ошибке для каждой команды, в том числе с небольшим списком аргументов, мы можем разумно предположить, что этот предел достигнут, потому что либо у вас очень большая переменная среды, либо совокупный размер среды переменных и их значений, переданных в выполненных команд больше, чем ARG _MAX.
Это может произойти, например, если вы по ошибке установили параметр POSIX allexport
, что приводит к тому, что все переменные оболочки будут помещены в среду, и определили множество переменных, возможно, посредством запуска различных функций завершения, некоторых из них кэшируют информацию в переменных.
Проверить с помощью:
echo $options[allexport]
Который должен сообщить off
. Если нет, проверьте файлы запуска, в которых установлен этот параметр. Может быть с set -a
, set -o allexport
, setopt allexport
, options[allexport]=on
или с другим возможным написанием этой опции (регистр и подчеркивание игнорируются, поэтому это также может быть setopt ALL_EXPORT
например ).
Некоторые другие вещи, которые вы можете попробовать:
Проверить текущий предел размера стека:
$ limit stacksize
stacksize 8MB
Проверить текущее значение ARG _МАКС.:
$ (typeset +x -m '*'; getconf ARG_MAX)
2097152
typeset +x -m '*'
удаляет все переменные среды. Это включает в себя $PATH
, но ваша система все равно сможет найти getconf
в $PATH
по умолчанию.
Проверьте размер окружения:
$ typeset -x | wc -c
4395
(это приближение, которое не включает переменные, которые не сопоставлены с переменными оболочки, подсчет может включать некоторые символы кавычек, добавленные typeset -x
, которых нет в значениях переменных, и он не учитывает учтите тот факт, что вам также необходимо подсчитать размер списка указателей на эти строки env ).
Ищите переменные среды, размер которых превышает 128 КБ:
$ LC_ALL=C
$ export test=${(l[132000])}
$ for v (${(k)parameters[(R)*export*]}) {(( (l=${(P)#v}) >= 131071 )) && echo "$v: $l"}
test: 132000
$ ls
ls:2: argument list too long: ls
Из отдельной оболочки, запущенной как root
, которая не затронута этой проблемой, вы также можете запустить:
strace -s150000 -vfe execve -p "$pid"
Где $pid
— это идентификатор процесса вашей оболочки, в которой возникла эта проблема. (см. вывод echo $$
), а затем попробуйте выполнить команду в этой оболочке.
strace
должен показать вам точный execve()
системный вызов, который выполняется и который не работает с E2BIG
, а также полный список аргументов и строк окружения (, усеченных до 150 000 байт каждый ), что, надеюсь, должно помогите определить проблему.