VBoxManage modifyvm "GE Win7 "--vrde on
ssh server VBoxManage startvm" GE Win7 "--type headless
rdesktop server : 3389
Помните, что никакой брандмауэр не блокирует трафик rdp (порт TCP 3389).
Как уже объяснил @schily, это не проблема оболочки, и ее нельзя обойти с помощью xargs
, цитирования, разделения на дополнительные эхо с помощью ;
и т. д. Весь текст из действия make передается как аргумент/с в один execve(2)
, и он не может быть длиннее, чем максимальный размер, разрешенный операционной системой.
Если вы используете GNU, сделайте (по умолчанию в Linux ), вы можете использовать его функцииfile
иforeach
:
TEST = $(shell yes foobar | sed 200000q)
/tmp/junk:
$(file >$@) $(foreach V,$(TEST),$(file >>$@,$V))
@true
.PHONY: /tmp/junk
Это напечатает все слова из $(TEST)
, разделенные символами новой строки, в файл с именем $@
. Он основан на аналогичном примере из руководства make .
Ваш Makefile, вероятно, можно было бы переработать во что-то более управляемое, не требующее причудливых функций GNU, но по фрагментам, которые вы разместили, трудно сказать, как это сделать.
Обновление:
Для точного фрагмента вопроса можно сделать что-то вроде этого:
.hgignore :.hgignore_extra
$(info Making $@)
$(file >$@.new)
$(file >>$@.new,# Automatically generated by Make. Edit.hgignore_extra instead.)
$(shell tail -n 2 $< >>$@.new)
$(file >>$@.new,)
$(file >>$@.new,# The following files come from the Makefile.)
$(file >>$@.new,syntax: glob)
$(foreach L, $(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES), $(file >>$@.new,$L))
@mv -f $@.new $@
@chmod a-w $@
.PHONY :.hgignore
Я его немного изменил, поэтому он сначала пишет в .hgignore.new
, и если все пойдет хорошо, то только потом перемещать .hgignore.new
в .hgignore
. Вам придется заменить отступы пробелами на табуляции, потому что этот тупой интерфейс искажает пробелы.
См. этот ответ , в частности эту цитату:
one argument must not be longer than MAX_ARG_STRLEN (131072). This might become relevant if you generate a long call like "sh -c 'generated with long arguments'".
С другой стороны, ограничение на общее количество передаваемых аргументов довольно велико, поэтому, может быть, вместо этого просто передавать их как отдельные аргументы, поскольку конечный результат echo
будет таким же?
Это просто удаляет "
из исходной команды:
@echo $(IGNORE_DIRS) $(CLEAN_FILES) $(CLEAN_DIRS) $(REALCLEAN_FILES) | tr ' ' '\n' >> $@
Надеемся, что этого достаточно, чтобы удерживать аргументы в пределах количества аргументов (, которое довольно велико )и длины каждого аргумента (, что больше не будет проблемой, поскольку каждый аргумент теперь короткий.)
ОБНОВЛЕНИЕ:Удаление кавычек на самом деле не исправит это полностью, так как make
запускает каждую команду в оболочке, используя эквивалент sh -c '...'
, где вся команда становится одним аргументом, поэтому она все равно будет привязан к предельной длине для отдельного аргумента, которая составляет 131 072 байта в Linux на платформе x86.
Ур -вопрос в таких случаях: зачем вы вообще это делаете? Похоже, вы пытаетесь создать какой-то файл.ignore, содержащий все файлы, которые предположительно являются либо выходными данными программы, либо глобусами. В первом случае я бы рекомендовал передавать вывод программы непосредственно в tr
(, если это строго необходимо, ), а затем в файл без передачи через промежуточную переменную. Если вы используете globs, вы можете использовать очень простой циклfor
:
for file in *
do
echo "$file" >> out.txt
done
(Escape, если необходимо, в вашем Makefile.)
В самых общих чертах:
xargs
, когда это действительно необходимо. echo
с и cat
с . В UNIX применяется следующее правило:
The following data forms the initial stack of a process:
- The sum of strlen() of all environment strings + final nul character per string
- The sum of strlen() of all argument strings + final nul character per string
- The environment array: n+1 environment strings * sizeof char *
- The argv array: n+1 argument strings * sizeof char *
- A few additional numbers
Все эти данные не должны превышать ARG_MAX
.
В предыдущей версии UNIX значение для ARG_MAX
было 10240 или 20480 байт .
SunOS -4.0 (, опубликованная в декабре 1987 г. ), увеличила это ограничение до 1 МБ
Версия Solaris -7.0 (, опубликованная в 1997 году ), представила поддержку 64-разрядных систем и во избежание практически меньшего ограничения на 64-разрядные системы (, вызванного большими env
и argv
массивами в качестве результат от большего char *
), ARG_MAX
был увеличен до 2 МБ для 64-битных программ.
Кстати, :Современные ОС, совместимые с POSIX, включают поддержку программы getconf
, а getconf ARG_MAX
печатает фактическое значение. В 64-разрядной версии Linux это возвращает 2 МБ , поэтому на первый взгляд кажется, что Linux использует улучшения SunOS....
Теперь давайте посмотрим наmake
:
Программа make
вызывает команды из Makefiles
через:
sh -ce command
где command
— это одиночный аргумент , то есть расширенная строка, которую вы видите в строке действия из Makefile
.
SunPro Make
ввел оптимизацию в начале 1990-х:
make
сам помечает командную строку и вызывает команду через :execv()
, чтобы избежать накладных расходов на вызов оболочки. Позднее gmake
и smake
приняли эту оптимизацию.
smake
представили еще одну оптимизацию в 2012 г.:
echo
, которая заканчивается на ;
, и если следующая командная строка не содержит метасимволов оболочки,echo
встроен в smake
, а команда после ;
выполняется через execv()
, чтобы уменьшить накладные расходы для современных систем сборки, которые обычно используют @
для подавления эха команды make
и вместо этого используют упрощенные вызовы echo
для облегчения понимания вывода make
(см., например, система Schily Makefile, представленная в феврале 1993 года ). Ни одно из этих make
правил не применяется к вашей make
командной строке, поскольку ваша командная строка содержит метасимволы оболочки. Итак, вся ваша команда вызывается через:
sh -ce command
, где command
— это отдельная строка с общим размером, вызванным вашим make-файлом.
Теперь кажется, что ядро Linux не совместимо ни с UNIX, ни с POSIX и налагает дополнительное ограничение, которого никогда не было в UNIX. Это дополнительное ограничение, по-видимому, основано на максимальной длине одной строки.
Если это действительно так, это дисквалифицирует Linux, так как не позволит использовать Linux в более крупных проектах, управляемых make
.
Думали ли вы о том, чтобы сообщить об ошибке людям, занимающимся ядром Linux?