У меня есть этот сценарий оболочки, сохраненный в файле: он выполняет некоторые основные подстановки строк.
#!/bin/sh
html_file=$1
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
Если я вставлю его в командную строку, он будет работать нормально:
$ html_file="/home/max/for_pauld/test_no_base64.html"
echo "html_file = $html_file"
substr=.pdf
pdf_file="${html_file/.html/.pdf}"
echo "pdf_file = $pdf_file"
дает
html_file = /home/max/for_pauld/test_no_base64.html
pdf_file = /home/max/for_pauld/test_no_base64.pdf
Это вывод из эха выше - он работает как задумано.
Но когда я вызываю сценарий, с
$ saucer "/home/max/for_pauld/test_no_base64.html"
Я получаю этот вывод:
html_file = /home/max/for_pauld/test_no_base64.html
/home/max/bin/saucer: 5: /home/max/bin/saucer: Bad substitution
Мой сценарий использует другую версию Bash или что-то? Мне нужно изменить мою линию Шебанга?
sh
иbash
. Я прочитаю об этом. Если вы не можете превратить ваш комментарий в ответ, я отмечу его как правильный.#!/usr/bin/env bash
как ваш shebang, и используйте заданные по порядку замены, как вы хотите, но с оговорками переносимости. И читайте: unix.stackexchange.com/a/48787/27616Ответы:
Что такое ш
sh
(или Shell Command Language) - это язык программирования, описанный стандартом POSIX . Она имеет множество реализаций (ksh88
,dash
, ...).bash
также может рассматриваться как реализацияsh
(см. ниже).Потому
sh
что это спецификация, а не реализация,/bin/sh
это символическая ссылка (или жесткая ссылка) на фактическую реализацию в большинстве систем POSIX.Что такое bash
bash
начиналась какsh
-совместимая реализация (хотя она предшествует стандарту POSIX на несколько лет), но со временем она приобрела множество расширений. Многие из этих расширений могут изменить поведение допустимых сценариев оболочки POSIX, поэтому сама по себеbash
не является допустимой оболочкой POSIX. Скорее, это диалект языка оболочки POSIX.bash
поддерживает--posix
переключатель, что делает его более POSIX-совместимым. Он также пытается имитировать POSIX, если вызывается какsh
.ш = баш?
Долгое время
/bin/sh
использовался для указания/bin/bash
на большинство систем GNU / Linux. В результате почти стало безопасным игнорировать разницу между ними. Но это начало меняться в последнее время.Вот некоторые популярные примеры систем
/bin/sh
, на которые нет указаний/bin/bash
(а на некоторых из которых они/bin/bash
могут даже не существовать):sh
на которыеdash
по умолчанию установлены;initramfs
. Он используетash
реализацию оболочки.pdksh
, потомок оболочки Korn. FreeBSDsh
является потомком оригинальной оболочки UNIX Bourne. У Solaris есть свой собственный,sh
который долгое время не был POSIX-совместимым; бесплатная реализация доступна из проекта Heirloom .Как вы можете узнать, на что
/bin/sh
указывает ваша система?Сложность в том, что это
/bin/sh
может быть символическая ссылка или жесткая ссылка. Если это символическая ссылка, портативный способ решить это:Если это жесткая ссылка, попробуйте
На самом деле
-L
флаг охватывает как символические, так и жесткие ссылки, но недостатком этого метода является то, что он не переносим - POSIX не требуетfind
поддержки-samefile
опции, хотя и GNU find, и FreeBSD find поддерживают ее.Линия Шебанг
В конечном счете, вам решать, какой из них использовать, написав строку «шебанг».
Например
будет использовать
sh
(и все, что происходит, чтобы указать),будет использовать,
/bin/bash
если это доступно (и не с сообщением об ошибке, если это не так). Конечно, вы также можете указать другую реализацию, например,Какой использовать
Для моих собственных сценариев я предпочитаю
sh
по следующим причинам:bash
, они должны иметьsh
Есть и преимущества в использовании
bash
. Его особенности делают программирование более удобным и похожим на программирование на других современных языках программирования. К ним относятся такие вещи, как локальные переменные и массивы. Plainsh
- очень минималистичный язык программирования.источник
/bin/sh
действительно является символической ссылкой на/bin/dash
.В дополнение к отличному ответу от @ Hunter.S.Thompson, я хотел бы отметить, что непереносимая часть сценария
Расширение
${variable/search/replace}
GNU. Но вы можете легко избежать этого с чистым POSIX:Вслед за Хантером это лучшее решение, чем изменение Шебанга на
#! /bin/bash
источник