LINUX.ORG.RU

Несоответствие мануала с действительностью

 


0

2

Прочитал манул, полез в файл parse.y в исходниках и понял что мануал не соответсвует тому как работает баш. Множество синтаксических конктрукций не задокументировано, а некоторые задокументированы неправильно.

Например:

for name; { echo $name; }

в мануеле нет констнукции for без do, тем неменее в баше есть несколько вариантов таких конструкций

также в while/until ; опциональна, хотя в мануле написано что нет



Последнее исправление: mishka06 (всего исправлений: 2)

и понял

  1. В процессе понимания можно было ошибиться. Пример - в слове «соответсвует» есть опечатка - пропущена буква. Это нормально - ошибаться.

  2. Могут быть ошибки в самой документации. Её авторы тоже люди, что тут такого?

Продолжайте ваше исследование.

Saakx
()

В man ksh есть такое:

for name [ in word ... term ] do list done

where term is either a newline or a ;. For each word in the specified word list, the parameter name is set to the word
and list is executed. If **in** is not used to specify a word list, the positional parameters ("$1", "$2", etc.) are used instead. For historical reasons, open and close braces may be used
instead of **do** and **done** (e.g., for i; { echo $i; }).
The exit status of a for statement is the last exit status of list; if list is never executed, the exit status is zero.

Так, что можете копать в сторону синтаксиса shell в первых юниксах. Явно подобный синтаксис оставили для совместимости с древними скриптами, но спрятали, чтобы в какой-то момент совсем удалить. Если будете его использовать, то в какой-то момент ваши скрипты превратятся в тыкву.

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от Saakx

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

mishka06
() автор топика

У меня

for name; { echo $name }
не работает, он считает что у этой строки должно быть продолжение, правда чего он там ждёт я не знаю

И такое тоже не работает

for name in a b c; { echo $name }

Так что скорее это ты неправильно понял исходники, а в документации всё норм.

firkax ★★★★★
()
Ответ на: комментарий от mishka06

От баша почти ничего не зависит, это всего лишь интерактивный шелл. Скрипты нормальные люди пишут для POSIX шелла (#!/bin/sh), его поведение описано в стандарте POSIX.

firkax ★★★★★
()
Ответ на: комментарий от mishka06

Где много? Я очень редко их вижу и это сразу признак того что их писал кто-то не слишком компетентный. Особенно удивляют ситуации когда файл .sh а внутри #!/bin/bash

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от mishka06

Расширение вообще не важно, главное, что указано в шебанг (#!/...), если ничего не указано и есть флаг исполнения - выполняется интерпретатором текущей оболочки.

Если это не ELF файл, а текстовый, конечно.

anonymous
()
Ответ на: комментарий от mishka06

По какому стандарту? В юниксах самих по себе никаких mime нет, это штука для электронной почты и веба. Ну и гуи с некоторых пор начали её использовать.

Файл .sh это файл который можно запустить командой /bin/sh filename.sh. Особенно если он без флага executable, но и с флагом это никуда не девается в целом. А команда /bin/sh должна (по стандарту POSIX) запускать шелл, который может выполнить любой корректный скрипт на POSIX шелле.

firkax ★★★★★
()
Ответ на: комментарий от anonymous

Нет, расширение важно. Шебанг нужен когда файл запускают так:

./filename.sh
кстати, встречались даже случаи скриптов с #!/bin/sh и башизмами внутри - работали на тех линуксах где sh симлинк на bash и не работали или глючили на других. Например у консольного стима было такое с pushd/popd внутри. Но хотя бы это вроде уже ушло в прошлое (или нет?).

Но если файл имеет расширение .sh - это как бы приглашение юзеру «меня можно запустить /bin/sh filename.sh», а уж есть у него исполняемый флаг или нет - не сильно важно в данном контексте (его могут и вообще не проверить, увидев .sh).

Если хочешь чтобы скрипт запускался строго через шебанг - лучше не ставить ему никакое расширение.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от mishka06

Ты ссылаешься на стандарт, что дескать есть какой-то миме тип sh.

А я говорю, насрать шелл на твой миме тип и какой-то стандарт для миме sh.

В консоли шелл читает то, что указано в шебанг и выполняет, если шебанг нет и это текс - сам интерпретирует или запускает как эльф, всё.

anonymous
()
Ответ на: комментарий от firkax

Первый раз такое слышу.

# bash.sh ; dirname /usr/local/bin/bash.sh ; cat /usr/local/bin/bash.sh ; ./bash.sh ; dirname ./bash.sh ; cat ./bash.sh ; echo $BASH_VERSION
Hello, World!
/usr/local/bin
#!/usr/bin/python3
print("Hello, World!")
Hello, World!
.
#!/usr/bin/python3
print("Hello, World!")
5.2.15(1)-release

Вот файл, с «раширением» sh, в нём через шебанг указан интерпретатор python3, всё прекрасно запускается.

anonymous
()

А можно было просто загуглить и не создавать унылый топик:

https://stackoverflow.com/a/38828936

…I’m told by the maintainer of bash that this is an undocumented feature that provides backwards compatibility with an undocumented feature in the original Bourne shell.

/thread

P.S. Да, bash — это последовательно петрифицируемый копролит из дендрофекальных велосипедов на костылях. Для всех, кто сталкивался с его внутренностями это не откровение. Теперь и вы знаете.

anonymous
()
Ответ на: комментарий от firkax

Это уже нюанс, кто дёргает системный вызов и проверяет наличие шебанг, сам шелл или ядро, как ты говоришь.

Смысл в том, что шебанг первоочерёден.

Спасибо за поправку, но на слово не верю.

anonymous
()

Наличие незадокументированных возможностей не является «несоответствием действительности». Всё, что описано в мануале, действительности соответствует. А то, что там чего-то нет — ну так он не претендует на полное описание вселенной.

Юзать подобные конструкции в скриптах я бы не стал, кстати. Раз нет в мануале, значит официально не поддерживается. Возьмут и перепишут в следующей версии parse.y как-то ещё, и посыпятся такие скрипты.

P.S. Я вообще предпочитаю скрипты на POSIX Shell писать, без башизмов. Но это уже каждому своё, конечно.

CrX ★★★★★
()
Ответ на: комментарий от firkax

От баша почти ничего не зависит, это всего лишь интерактивный шелл. Скрипты нормальные люди пишут для POSIX шелла (#!/bin/sh), его поведение описано в стандарте POSIX.

К сожалению, первое утверждение не совсем соответствует действительности. Скриптов с #!/usr/bin/env bash или #!/bin/bash много. Может их и не «нормальные» люди пишут, но легче от этого не становится.

Но да, спасибо, что хоть эти недокументированные фичи в скриптах никто не юзает, даже если юзают башизмы.

CrX ★★★★★
()
Ответ на: комментарий от firkax

встречались даже случаи скриптов с #!/bin/sh и башизмами внутри - работали на тех линуксах где sh симлинк на bash и не работали или глючили на других. Например у консольного стима было такое с pushd/popd внутри. Но хотя бы это вроде уже ушло в прошлое (или нет?).

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

Но если файл имеет расширение .sh - это как бы приглашение юзеру «меня можно запустить /bin/sh filename.sh»

А вот и нет. Расширение .sh может иметь и именно баш-скрипт в том числе. Расширение лишь помогает юзеру узнать, что это примерно, и чем его править при необходимости. Запуск скриптов с помощью /bin/sh filename.sh считается нубской ошибкой, и за это бьют по рукам и учат делать chmod +x.

CrX ★★★★★
()

В Linux давно появился нормальный удобный shell — powershell. Но кто-то продолжает плакаться, колоться, но использовать все эти шеллы из 70-х. Да, для своего времени это были неплохие попытки, но использовать их 21 веке? Зачем?

anarquista ★★★★★
()
Ответ на: комментарий от CrX

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

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от firkax

если вникать в корень :) то вообще до лампочки что там после #! хоть sh хоть bash хоть python… ядро просто запустит бинарь по указному пути и передаст ему строчку символов - всё.
к самому файлу лишь одно требование - иметь флаг выполняемого.
пруф ищется элементарно. https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 2)
Ответ на: комментарий от CrX

Расширение .sh может иметь и именно баш-скрипт в том числе. Расширение лишь помогает юзеру узнать, что это примерно, и чем его править при необходимости. Запуск скриптов с помощью /bin/sh filename.sh считается нубской ошибкой, и за это бьют по рукам и учат делать chmod +x.

Кем считается? По мне так нубская ошибка это баш скрипт расширением .sh называть. chmod +x должен делать тот, кто этот файл положил на указанное место, а не тот, кто думает как его запустить. Если исполняемого флага нет, значит единственный вариант - /bin/sh filename.sh, и даже если он есть - файл с расширением .sh не должен ломаться от такого запуска. Если файл не рассчитан на запуск с явным указанием /bin/sh - не надо делать ему расширение .sh.

и за это бьют по рукам

Так что и бить по рукам надо за сувание не тех шеллов в .sh.

firkax ★★★★★
()
Ответ на: комментарий от anonymous

Баша нет в большинстве современных серверных ОС (то есть его дефолтно нет в фрибсд, но есть в более редком солярисе), а обобщать свои десктопные привычки (линукс) не следует.

firkax ★★★★★
()
Ответ на: комментарий от firkax

кто встроен, в какую дефолтную инсталяцию, какого дистра, какой список ??
опять личное мнение на весь мир натягиваешь %)
в #! можно использовать любой бинарь, имеющийся в системе.

pfg ★★★★★
()
Ответ на: комментарий от pfg

Иди проспись. У тебя проблемы с пониманием текстов.

в #! можно использовать любой бинарь, имеющийся в системе.

Я с этим и не спорил, если что.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

Bash – свалка из нипойми чего, созданная вообще без какого либо проектирования, синтаксис полностью наглухо упопот, и по этим причинам баш нинужен. Лучше потратьте своё время на изучение документации чего-то действительно полезного.

apt_install_lrzsz ★★★★
()
Ответ на: комментарий от firkax

Кем считается?

Аудиторией многих форумов, IRC-каналов и сайтов, на которых я это наблюдаю.

По мне так нубская ошибка это баш скрипт расширением .sh называть.

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

chmod +x должен делать тот, кто этот файл положил на указанное место, а не тот, кто думает как его запустить.

Это обычно один и тот же человек.

Если файл не рассчитан на запуск с явным указанием /bin/sh - не надо делать ему расширение .sh.

Это ты только что выдумал. Ну не делай, я не против. С другой стороны, ты-то понятно, что не сделаешь — ведь ты, как и я, такие скрипты сразу пишешь на POSIX Shell. Только таких файлов в интернете огромное количество, и меньше их не станет.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от firkax

Питон с перлом можно понять - они чаще встроены в дефолтную инсталляцию, но почему в этом списке есть руби и нет пхп - совершенно непонятно.

Ответ прост — потому что когда я писал это сообщение, руби мне пришёл на ум раньше. Не во всём есть какой-то великий смысл. Мог написать и пхп, без разницы, в скобках скорее примеры — в счёт того, что есть те, кто недолюбливает именно питон.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)