nixp.ru v3.0

19 октября 2017,
четверг,
10:19:37 MSK

DevOps с компанией «Флант»
Anarchist написал 3 сентября 2008 года в 14:44 (1221 просмотр) Ведет себя как мужчина; открыл 258 тем в форуме, оставил 4097 комментариев на сайте.

FreeBSD 6.2-RELEASE #0

bash-3.2.25

expr $RANDOM % 4

Отрабатывает как и предполагалось, как и надо.

Но стоит только вставить в скрипт следующего содержания (запускаемый тут же):

#!/usr/local/bin/bash
expr $RANDOM % 4
exit 0

Ошибка

expr: syntax error

Раньше (когда был bash постарее) — работало прекрасно.

В чём проблема?

ЗЫ: Проврил на своей рабочей станции (Gentoo Linux).

app-shells/bash

Installed versions: 3.2_p33

Всё работает. Бзди-специфичная бага.

myst

Поставь «;» на всякий случай.

Anarchist
myst
Поставь «;» на всякий случай.

Эффект тот же.

При изменении интерпретатора на /bin/sh — аналогично.

Дмитрий Шурупов

А переменная $RANDOM там определена? Похоже, проблема в этом. Может, какой ее аналог поискать надо…

Anarchist
Dmitry Shurupov
А переменная $RANDOM там определена? Похоже, проблема в этом. Может, какой ее аналог поискать надо…

Шурупов. Ты невнимателен. Не выспался?

Я же писал, что

$ expr $RANDOM % 4

работает как и предполагается.

Проблемы начинаются когдя я пробую генерить случайные числа в скрипте.

Если бы переменная RANDOM не была определена, они бы начались намного раньше.

Дмитрий Шурупов

А ты не наблюдателен.

Добавь «echo $RANDOM» в этом своем скрипте и увидишь, что переменная в окружении скрипта не определена.

Через bash ли ты его вообще вызываешь? У меня через bash все окей, через sh — твоя ошибка, а $RANDOM не определена.

Anarchist
Dmitry Shurupov
Добавь «echo $RANDOM» в этом своем скрипте и увидишь, что переменная в окружении скрипта не определена.

Угу.

Dmitry Shurupov
Через bash ли ты его вообще вызываешь? У меня через bash все окей, через sh — твоя ошибка, а $RANDOM не определена.

Всё. Блин. Сам дурак.

Короче, назначать бит 'x' мне было естественно в лом.

Скрипт пускал посредством

sh random.sh

Ну и он при таком обращении не отрабатывал как положено первую строку скрипта

#!/usr/local/bin/bash

В Gentoo Linux тот же эксперимент отрабатывался ПОЛНОСТЬЮ адекватно.

Дмитрий Шурупов

> Скрипт пускал посредством

О! Ч. и т.д. Я, к счастью, сначала сделал то же самое и тогда осознал проблему.

> В Gentoo Linux тот же эксперимент отрабатывался ПОЛНОСТЬЮ адекватно.

Я не уверен, что Gentoo Linux при этом прав. Но это уже совсем другая тема…

Anarchist
Dmitry Shurupov
> В Gentoo Linux тот же эксперимент отрабатывался ПОЛНОСТЬЮ адекватно.

Я не уверен, что Gentoo Linux при этом прав. Но это уже совсем другая тема…

Предлагаю пофлеймить обсудить какое поведение здесь является правильным :)

Дмитрий Шурупов
Anarchist
Предлагаю пофлеймить обсудить какое поведение здесь является правильным :)

Оно «неправильное». Мне тут даже продемонстрировали, почему:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Июл 11 22:01 /bin/sh -> bash

:-D

metal
Dmitry Shurupov
Оно «неправильное». Мне тут даже продемонстрировали, почему:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Июл 11 22:01 /bin/sh -> bash

:-D

Вообще bash должен вести себя как sh если его запустили как sh.

Дмитрий Шурупов

А если в Gentoo нет самого sh, то кто гарантирует полную «эмуляцию» башем оригинального шелла?

metal

И вообще в ArchLinux:

bash-3.2$ bash --version
GNU bash, version 3.2.39(1)-release (i686-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

У меня одинаково работает и sh test.sh, и при обычном запуске, причем независимо от того, какой интерпретатор.

Дмитрий Шурупов

А sh там есть? Или тоже symlink на bash? ;-)

metal
Dmitry Shurupov
А sh там есть? Или тоже symlink на bash? ;-)

Конечно symlink :D

Думаю это все-таки ошибка в современных версиях bash. RANDOM это фишка именно bash, если верить man.

Дмитрий Шурупов

Почему ошибка? Просто bash не хочет себя вести как sh ;-)

metal

Из man bash.

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

Думаю тут сохранить совместимость нет проблем, не даром в debian занялись dash.

Дмитрий Шурупов

В Ubuntu вот как раз sh ссылается на dash и отрабатывает, как описал Анархист ($RANDOM не определена).

Anarchist
Dmitry Shurupov
Оно «неправильное». Мне тут даже продемонстрировали, почему:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Июл 11 22:01 /bin/sh -> bash

:-D

Ну и что?

Здесь разницы между sh || bash || csh || что ещё по вкусу быть не должно.

Интерпретатор (не важно какой) читает первую строку файла

#!/usr/local/bin/bash

А дальше он по идее должен был бы запустить этот самый /usr/local/bin/bash и остальную часть скрипта интерпретировать как команды интерпретатора указанного в заголовке.

С этой точки зрения сущность (и степень определённости в нём переменной RANDOM) /bin/sh (если только он является адекватным Unix’овым командным процессором): симлинки ли он и если симлинк, то на что указывает — совершенно не важна.

Anarchist
Dmitry Shurupov
А если в Gentoo нет самого sh

Чем мне нравится Gentoo, так это отсутствием лишних компонентов.

Дмитрий Шурупов

С чего бы это он должен что-то еще запускать?! Он игнорирует команду, начинающуюся с «#!».

В man по bash учет «#!» упоминается только в контексте файлов. В остальных случаях «#» — комментарий, так что уже неважно, что там идет после…

Anarchist
Dmitry Shurupov
С чего бы это он должен что-то еще запускать?! Он игнорирует команду, начинающуюся с «#!».

В man по bash учет «#!» упоминается только в контексте файлов. В остальных случаях «#» — комментарий, так что уже неважно, что там идет после…

Насколько я помню читанную в древние времена документацию, '#' конечно обозначает комментарий и часть строки следующая за ним игнорируется.

Но для первой строки файла — особый подход. Если после него идёт восклицательный знак путь к программе, то остальная часть файла интерпретируется как входные данные для этой программы.

Или это — личные заморочки писавшего?

Anarchist
Dmitry Shurupov
С чего бы это он должен что-то еще запускать?! Он игнорирует команду, начинающуюся с «#!».

В man по bash учет «#!» упоминается только в контексте файлов. В остальных случаях «#» — комментарий, так что уже неважно, что там идет после…

bash здесь совершенно ни при чём!

Это — более основополагающий уровень!

Помнится, шаманил я с какой-то криво портированной программкой под фрёй. Были там скрипты.

Строка в заголовке

#!/bin/bash

Естественно не работает (ну нету такого файла).

Меняю на

#!/bin/sh

Не работает. Скрипт написан в расчёте на функциональность bash’а.

Исправляю на

#!/usr/local/bin/bash

И всё работает.

Если бы '#' всегда и везде означал комментарий — такого бы не было.

Осталось формализовать участие во всём этом бита исполнения — и будет полное счастье.

myst
Anarchist
Насколько я помню читанную в древние времена документацию, '#' конечно обозначает комментарий и часть строки следующая за ним игнорируется.

Но для первой строки файла — особый подход. Если после него идёт восклицательный знак путь к программе, то остальная часть файла интерпретируется как входные данные для этой программы.

Или это — личные заморочки писавшего?

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

Anarchist
myst
Особый подход к #! имеет системный загрузчик, а для всего остального это просто «#!».

В таком случае как ты объяснишь мой предыдущий комментарий?

myst

А я не вижу противоречий.

Anarchist
myst
А я не вижу противоречий.

Интересно…

Дело ведь в том, что я говорю про в-общем-то обыкновенные скрипты, которые с системным загрузчиком никаким боком не пересекаются.

myst

Если ты их запускал

$ sh script

тогда, действительно странно.

А если:

$ ./script

то это обслуживает системный загрузчик.

Anarchist
myst
Если ты их запускал

$ sh script

тогда, действительно странно.

А если:

$ ./script

то это обслуживает системный загрузчик.

Это я и имел в виду, когда говорил о роли бита исполнения.

Благодарю за уточнение.