Почему этот сценарий работает в терминале, а не из файла?

Я бы не стал не пробуйте его на компакт-диске (хотя вполне может быть, что мои старые опасения по поводу буферизации устарели), но он отлично работает с USB-ключом; например:

curl -L http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso | sudo dd of=/dev/sdf

загружает текущий сетевой установщик Debian и записывает его в ключ sdf .

Это работает, потому что dd по умолчанию читает из своего стандартного ввода, если не указан параметр if . Параметр -L для curl указывает ему следовать перенаправлениям.

На самом деле нет необходимости использовать dd ; как root ,

curl -L http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso > /dev/sdf

тоже работает нормально.

(Убедитесь, что вы правильно установили устройство! С помощью такой команды можно легко уничтожить не тот диск ...)

19
19.07.2017, 10:40
2 ответа

Что такое ш

sh(или язык команд оболочки )— это язык программирования, описанный POSIX. стандарт . Имеет множество реализаций (ksh88, dash,... ). bashтакже может быть считается реализациейsh(см. ниже ).

Поскольку sh— это спецификация, а не реализация, /bin/sh— символическая ссылка. (или жесткая ссылка )на фактическую реализацию в большинстве систем POSIX.

Что такое баш

bashначинался какsh-совместимая реализация (, хотя она предшествовала стандарту POSIX на несколько лет ), но с течением времени она приобрела множество расширений. Многие из этих расширений могут изменить поведение допустимых сценариев оболочки POSIX, поэтому сам по себе bashне является допустимой оболочкой POSIX. Скорее, это диалект языка оболочки POSIX.

bashподдерживает переключатель --posix, что делает его более совместимым с POSIX -. Он также пытается имитировать POSIX, если вызывается как sh.

ш = баш?

Долгое время /bin/shуказывал на /bin/bashв большинстве систем GNU/Linux. В результате стало почти безопасно игнорировать разницу между ними. Но это начало меняться в последнее время.

Некоторые популярные примеры систем, в которых /bin/shне указывает на/bin/bash(и на некоторых из которых /bin/bashможет даже не существовать ), являются:

  1. Современные системы Debian и Ubuntu, которые по умолчанию создают символическую ссылку shна dash;
  2. Busybox , который обычно запускается во время загрузки системы Linux как часть initramfs. Он использует реализацию оболочки ash.
  3. BSD и вообще любые системы, отличные от -Linux. OpenBSD использует pdksh, потомок оболочки Korn. FreeBSD shявляется потомком оригинальной оболочки UNIX Bourne. У Solaris есть собственный sh, который долгое время не был совместим с POSIX -; бесплатная реализация доступна в проекте Heirloom .

Как узнать, на что указывает /bin/shв вашей системе?

Сложность заключается в том, что /bin/shможет быть символической ссылкой или жесткой ссылкой. Если это символическая ссылка, переносимый способ ее разрешения:

% file -h /bin/sh
/bin/sh: symbolic link to bash

Если это жесткая ссылка, попробуйте

% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash

Фактически, флаг -Lраспространяется как на символические, так и на жесткие ссылки. но недостаток этого метода в том, что он не переносимый — POSIX не требуетfindдля поддержки опции -samefile, хотя и GNU find , и FreeBSD find поддерживают его.

Линия Шебанг

В конце концов, вам решать, какой из них использовать, написав строку «shebang».

.

#!/bin/sh

будет использоватьsh(и что бы это ни случилось, чтобы указать на ),

#!/bin/bash

будет использовать /bin/bash, если он доступен (, и выдаст сообщение об ошибке, если он не ). Конечно, вы также можете указать другую реализацию, например.

#!/bin/dash

Какой использовать

Для собственных сценариев я предпочитаю shпо следующим причинам:

  • стандартизирован
  • он намного проще и легче в освоении
  • он переносим между системами POSIX — даже если у них нет bash, они должны иметьsh

Использование bashтакже имеет свои преимущества. Его функции делают программирование более удобным и похожим на программирование на других современных языках программирования. К ним относятся такие вещи, как локальные переменные с областью действия и массивы. Plain sh— очень минималистичный язык программирования.

39
27.01.2020, 19:44

В дополнение к отличному ответу @Hunter.S.Thompson я хотел бы отметить, что непереносимая часть скрипта -— это

pdf_file="${html_file/.html/.pdf}"

${variable/search/replace}является расширением GNU. Но этого легко избежать с помощью чистого POSIX :

.
pdf_file="${html_file%.html}".pdf

Вслед за Хантером, это лучшее решение, чем изменение шебанга на#! /bin/bash

23
27.01.2020, 19:44

Теги

Похожие вопросы