systemd защищает /proc :ProtectProc и ProcSubset

Как Крис говорит , аргументы формы variablename=anythingрассматриваются как присвоение переменной (, которое выполняется во время обработки аргументов, в отличие от (более новых)-v var=valueкоторые выполняются перед операторами BEGIN)вместо имен входных файлов.

Это может быть полезно в таких случаях, как:

awk '{print $1}' FS=/ RS='\n' file1 FS='\n' RS= file2

Где вы можете указать различные FS/ RSдля каждого файла. Он также широко используется в:

awk '!file1_processed{a[$0]; next}; {...}' file1 file1_processed=1 file2

Какая версия более безопасна:

awk 'NR==FNR{a[$0]; next}; {...}' file1 file2

(который не работает, если file1пусто)

Но это мешает, когда у вас есть файлы, имя которых содержит =символов.

Теперь это проблема только тогда, когда то, что осталось от первого =, является действительным awkименем переменной.

То, что составляет допустимое имя переменной в awk, более строго, чем в sh.

POSIX требует, чтобы это было что-то вроде:

[_a-zA-Z][_a-zA-Z0-9]*

Только с символами переносимого набора символов. Однако /usr/xpg4/bin/awkSolaris 11, по крайней мере, не соответствует требованиям в этом отношении и допускает использование любых буквенных символов в локали в именах переменных, а не только -zA -Z.

Таким образом, аргумент типа x+y=foo, =barили ./foo=barпо-прежнему обрабатывается как имя входного файла, а не как присваивание, поскольку то, что осталось от первого =, не является допустимым именем переменной. Такой аргумент, как Stéphane=Chazelas.txt, может быть, а может и не быть, в зависимости от реализации awkи локали.

Вот почему с awk рекомендуется использовать:

awk '...'./*.txt

вместо

awk '...' *.txt

, например, чтобы избежать проблемы, если вы не можете гарантировать, что имя файлов txtне будет содержать символы =.

Кроме того, имейте в виду, что такой аргумент, как -vfoo=bar.txt, может рассматриваться как вариант, если вы используете:

awk -f file.awk -vfoo=bar.txt

(также относится к awk '{code}' -vfoo=bar.txtс awkиз busybox версий до 1.28.0, см. соответствующий отчет об ошибке).

Опять же,использование ./*.txtработает вокруг этого (использование префикса ./также помогает с файлом с именем -, который в противном случае awkпонимается как значение стандартный ввод вместо ).

Вот почему

#! /usr/bin/awk -f

Шебанги на самом деле не работают. В то время как var=valueможно обойти, исправив , значения ARGV(добавляют префикс ./)в операторе BEGIN:

.

#! /usr/bin/awk -f
BEGIN {
  for (i = 1; i < ARGC; i++)
    if (ARGV[i] ~ /^[_[:alpha:]][_[:alnum:]]*=/)
      ARGV[i] = "./" ARGV[i]
}
# rest of awk script

Это не поможет с опциями, так как их видит скрипт awk, а не скрипт awk.

Одна потенциальная косметическая проблема с использованием этого префикса ./заключается в том, что он заканчивается в FILENAME, но вы всегда можете использовать substr(FILENAME, 3), чтобы удалить его, если он вам не нужен.

Реализация GNU awkустраняет все эти проблемы с помощью опции -E.

После -Egawk ожидает только путь awkскрипта (, где -по-прежнему означает stdin ), а затем только список путей к входным файлам (, а там даже не -обрабатывается особым образом ).

Специально разработан для:

#! /usr/bin/gawk -E

shebangs, где список аргументов всегда является входными файлами (обратите внимание, что вы по-прежнему можете редактировать этот ARGVсписок в операторе BEGIN).

Вы также можете использовать его как:

gawk -e '...awk code here...' -E /dev/null *.txt

Мы используем -Eс пустым скриптом (/dev/null), чтобы гарантировать, что эти *.txtпоследующие файлы всегда обрабатываются как входные файлы, даже если они содержат символы =.

0
14.03.2021, 00:20
1 ответ

Задан вопрос вверх по течению , после ответа он будет опубликован здесь.

Редактировать :это возможно, но с не -пользователем root. Это привело к обновлениям документации .

0
18.03.2021, 22:25

Теги

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