Рядок Shebang з командою `#! / Usr / bin / env --argument` не працює в Linux


53

У мене простий сценарій:

#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"

У моєму вікні OSX працює нормально:

osx% ./script.rb
hi

Однак у моєму вікні linux це помилка

linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

Якщо я запускаю лінію shebang вручну, вона прекрасно працює

linux% /usr/bin/env ruby --verbose ./script.rb
hi

Але я можу повторити помилку, якщо впакувати ruby --verboseв один аргумент доenv

linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

Тому я думаю, що це питання щодо того, як envтрактується скидання лінії shebang. Я використовую GNU coreutils 8.4 env:

linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard Mlynarik and David MacKenzie.

Це здається дивним. Це поширена проблема з цією версією env, чи тут відбувається щось інше, чого я не знаю?



Те саме тут з coreutils 8.17. Дивно. Повідомляючи Fedora, оскільки це прямо суперечить тому, що написано в посібнику.
vonbrand

@vonbrand Що сказала Fedora? "Нам все одно".
кіт

Відповіді:


44

Схоже, це тому, що Linux (на відміну від BSD) передає лише один аргумент команді shebang (в даному випадку env).

Про це широко обговорювалося в StackOverflow .


3
див. також цю сторінку для огляду поведінки в різних Юнісах.
Стефан Шазелас

4
Не вдалося вказати специфікацію. Боже мій.
Конрад Рудольф

3
Якщо під "специфікацією не вдається" ви маєте на увазі, що всі системи Unix повинні прийняти більше 1 аргументу, то я на 100% згоден з вами :)
Alexander Mills

Не стільки "linux", скільки GNU.
воля

5

Знайдено це через коментар @rampion:

Що відбувається, це те, що ядро ​​обробляє перші два символи файлу, шукаючи # !. Якщо такі знайдені, то він пропускає всі символи простору, шукаючи непробільний символ, і витягує шлях інтерпретатора, який повинен бути реальним виконуваним, а не іншим сценарієм, хоча Linux розширює це, щоб дозволити рекурсивну обробку сценарію. Виявивши, що потім він переходить до першого непробільного символу, звідки переходить до наступного символу нового рядка і передає це як єдиний аргумент команді. Немає «оболонки» обробки лапок чи інших мета символів. Це все дуже просто і жорстоко. Тому ви не можете захоплюватися можливостями. Ви отримуєте рівно один аргумент білого простору, і «perl -w» - це те, що ядро ​​бачить тут і передає.

Джерело: http://lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.