Поширення сценарію: Чи слід використовувати / bin / gawk або / usr / bin / gawk для shebang?


12

Зазвичай це gawk в / bin або / usr / bin? Я б пішов з цим, #!/usr/bin/env gawkале тоді я не можу використовувати аргументи. Зараз я використовую #!/bin/gawk -f. Сценарій дуже довгий і містить безліч одиничних цитат і працює зі stdin.

У посібнику GNU Awk є розділ 1.1.4 Виконані програми awk, де він використовує #! / Bin / awk у своєму прикладі, але продовжує говорити:

Зауважте, що на багатьох системах awkможна знайти /usr/binзамість in /bin. Caveat Emptor.

Що робить більшість людей? Я читав sed нібито стандартизований в / bin, тоді як perl нібито стандартизований в / usr / bin (та сама сторінка, що і посилання sed, але вони не дозволять мені зробити третє посилання на цю посаду). А як щодо awk / gawk? Хтось знає, що є більш поширеним чи популярним?


Для чого ви використовуєте -f? Не /bin/gawkвистачає? Також це може бути актуальним.
terdon

Відповіді:


7

Шебанг не мав бути таким гнучким . Можливо, є деякі випадки, коли функціонування другого параметра працює , я думаю, що FreeBSD є одним із них.

Очікується, що в ньому з'явиться більшість утиліт, що постачаються з ОС /usr/bin/.

У попередні дні UNIX зазвичай було /usr/встановлено NFS або деякі менш дорогі носії для економії місцевого дискового простору та витрат на робочу станцію. /bin/повинен був мати все необхідне для завантаження в режимі одного користувача . Оскільки /usr/він не був встановлений на надійному носії, /bin/увімкнув достатню кількість утиліт, щоб зробити його досить зручним для загального адміністрування та усунення несправностей.

Це було успадковано в Linux спочатку, але оскільки дисковий простір вже не є проблемою і в більшості випадків /usr/знаходиться в кореневій файловій системі, теперішня тенденція полягає в переміщенні всього /usr/bin(принаймні, у світі Linux). Тож очікується, що там знайдеться більшість комунальних послуг, встановлених дистрибутивом. Навіть самі основні утиліти, як cp, rm, і lsт.д. (ну, ще немає).

Щодо вибору shebang Традиційно це адміністратори чи користувачі мають редагувати відповідно до свого оточення. Бо всі розробники знають, що в інших системах інтерпретатор може бути в будь-якій точці файлової системи (наприклад /usr/local/bin, /opt/gawk-4.0.1/bin). Правильно упаковані сценарії (rpm, deb тощо) поставляються або залежно від пакета distro (тобто, у інтерпретатора є відоме місце розташування), або зі скриптом config, який встановлює належний хешбанг під час встановлення.


14

Якщо вам не потрібно передавати аргументи команді, тоді #!/usr/bin/env gawkце шлях, проте багато ядер (включаючи Linux) приймають лише один аргумент для програм shebang.

В іншому випадку ви можете зробити програму поліглоту, яка є оболонкою оболонки та сценарієм awk. Ось один для awk.

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

Аналіз оболонки:

  • true + /;- команда true(яка нічого не робить) з двома інертними аргументами +і /.
  • Заклик до gawk. Це може бути будь-який фрагмент оболонки, який не містить нових рядків і де написані косої риски \/(оболонка не проти, крім цитат).
    Виклик використовує execдля заміни оболонки gawk замість виконання gawk як підпроцесу.
  • exit;- вийдіть з оболонки, якщо gawk не був знайдений. Все після цього ігнорується, за винятком того, що він повинен бути дійсним синтаксисом оболонки у випадку, якщо оболонка намагається проаналізувати весь рядок перед тим, як почати його виконувати.

Awk розбір:

  • Біт між косою рисою є регулярним виразом.
  • true + /REGEX/- умова. trueє невизначеною змінною, тому її числове значення дорівнює 0, не те, що це має значення.
  • {} - Якщо зазначена умова виконується, нічого не робіть.

5

Пропоноване рішення Жиля - це дійсно дуже хороший підхід (нарешті, маємо репутацію проголосувати на своїй посаді :)).

У будь-якому випадку, наскільки я розумію execкоманду, вона робить exitправо після неї непотрібним, фактично недосяжним, оскільки процес оболонки замінюється на awk.

Крім того, щоб дозволити awkскрипту отримати доступ до своїх параметрів виклику, я запропонував би деякі зміни у запропонованому рішенні:

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

-a "$0"Дозволяє сценарій , щоб мати доступ до його імені виклику, в іншому випадку він завжди буде отримати awkабо gawkпри зверненні до ARGV[0]змінної. Так само, що "$@"дозволяє скрипту отримувати доступ до решти параметрів у ARGV[1...N]масиві, а --попередній він дозволяє сценарію отримувати -<something>аргументи без gawk їх інтерпретації.

Варто пам’ятати / враховувати одне, що потрібно додати exit(0);оператор у кінці BEGIN { ... }блоку програми awkскриптів, інакше awkзагрожуватиме всі параметри, передані скрипту у вигляді вхідних файлів. (Зверніть увагу, що це взагалі не має нічого спільного з exitзаявою, яку ми видалили з true + ...рядка. Це було недоступне твердження оболонки, поки цей запропонований вихід знаходиться в коді awk).


Це exit(0)було дуже корисно! Крім того, для користувачів Macos дивіться цю суть: Хороший портативний awk shebang знайти непросто.
Seamus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.