Какое особое значение имеет «#» в образец расширения параметра?

Я бы использовал sed

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

Декодировал синтаксис sed s / find / replace /:

  • s /^.* - подстановка, начиная с начала строки ( ^ ), за которым следует что угодно (. * ) до ...
  • \ ( - начать именованный блок
  • Conctetuer. * elit \. - соответствует первому слову , все (. * ) до последнего слова (в данном случае, включая конечную (экранированную) точку), вы хотите сопоставить
  • \) - завершить именованный блок
  • сопоставить все остальное (. * ) до конца строки ( $ )
  • / - завершить заменяющий раздел поиска
  • \ 1 - заменить блоком имени между \ ( и \) выше
  • / - завершить замену
13
23.06.2018, 22:26
4 ответа

Использование getconf ARG_MAXдля создания длинного списка xи вызов внешней утилиты с этим аргументом приведет к ошибке «Слишком длинный список аргументов»:

$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long

Окружающая среда и длина строки /bin/echoбудут включены в то, что вызывает ошибку, поэтому мы можем попытаться найти максимально возможное число, вычитая эти:

$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin

(Я запустил эту оболочку с env -i sh, поэтому в окружении есть только переменная PATH)

$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long

Еще слишком долго. Насколько?

i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
    i=$(( i + 1 ))
done

Этот цикл завершается для i=8.

Итак, есть четыре байта, которые я не могу сразу объяснить (четыре из восьми должны быть для имени переменной среды PATH). Это нулевые ограничители для четырех строк PATH, значение PATH, /bin/echoи длинная строка из xсимволов.

Обратите внимание, что каждый аргумент завершается нулем, поэтому чем больше аргументов у команды, тем короче может быть их общая длина.


Кроме того, просто чтобы показать эффект большого окружения:

$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )

$ /bin/echo hello
sh: /bin/echo: Argument list too long

$ /bin/echo
sh: /bin/echo: Argument list too long
10
27.01.2020, 19:52

Во многих дистрибутивах Linux текущее значение ARG _MAX можно узнать, запустив

getconf ARG_MAX

Простой способ сгенерировать сообщение «Слишком длинный список аргументов» состоит в том, чтобы предоставить длинный список аргументов; например, в моей системе

/bin/echo "$(find / -xdev 2> /dev/null)"

работает, но

/bin/echo "$(find / -xdev 2> /dev/null)" "$(find / -xdev 2> /dev/null)"

производит

bash: /bin/echo: Argument list too long

Подробное обсуждение в -см. в разделе Слишком длинный список аргументов для команд rm, cp, mv " в Stack Overflow.

П.С. Рассматриваемая длина - это фактический объем памяти, необходимый для хранения аргументов и среды. Это не связано с числом аргументов.

8
27.01.2020, 19:52

Вместо вывода списка всех файлов в системе, что занимает вечность и не работает на разреженных системах, команда

/bin/echo {1..200000}

— гораздо более быстрый (163 мс )способ генерировать ошибку. Для меня ARG_MAX— это2097152(2 097 152 порядка 2 миллионов ), но команда по-прежнему ошибается.

Если в вашей оболочке нет {start..end}, вы можете использовать более медленный (, но все же более быстрый, чем перечисление файлов)

/bin/echo $(seq 1 200000)

Если какая-либо из команд не работает, просто увеличивайте конечное значение до тех пор, пока оно не сработает, пока bashне закончится память или пока seqне сможет больше считать.

6
27.01.2020, 19:52

Чтобы было проще запустить новую оболочку (exit, когда закончите )и установите ограничение на более низкое значение (100 кбайт):

$ bash
$ ulimit -s 100

В приведенном вами примере может возникнуть ошибка:

$ touch {1..100000}.jpg
bash: /usr/bin/touch: Argument list too long

Но лучше использовать что-то вроде echo. Поймите, что встроенная функция может не вызвать ошибку, эта команда должна работать правильно:

$ echo {000001..100000}6789

Также обратите внимание, что количество байтов значительно превышает предел, установленный выше (1,1 Мбайт):

$ echo {000001..100000}6789 | wc -c
1100000

Но эта команда не работает:

$ /bin/echo {000001..100000}6789
bash: /bin/echo: Argument list too long

Ограничение задается размером списка аргументов в байтах, добавленным к размеру среды оболочки.

6
27.01.2020, 19:52

Теги

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