shとは何ですか?

shとは何ですか?

このシェルスクリプトをファイルに保存しました。このスクリプトはいくつかの基本的な文字列置換を実行します。

#!/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

上記のecho出力は次のとおりです。期待どおりに動作します。

しかし、スクリプトを呼び出すと

$ 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や他のものを使用していますか? Shebangラインを変更する必要がありますか?

答え1

shとは何ですか?

sh(またはShell Command Language)は、次のように開発されたプログラミング言語です。POSIX規格。多くの実装があります(ksh88、、、dash...)。bash実装と見なすこともできますsh(下記参照)。

shこれは実装ではなく仕様なので、/bin/shほとんどのPOSIXシステムではシンボリックリンク(またはハードリンク)の実際の実装です。

バッシュとは?

bashもともとは互換性の実装のために意図されていましたが、sh(POSIX標準よりも数年前にありますが)、時間の経過とともに多くの拡張が行われていました。これらの拡張の多くは、有効なPOSIXシェルスクリプトの動作を変更できるため、bashそれ自体は有効なPOSIXシェルではありません。代わりにPOSIXシェル言語の方言です。

bashスイッチのサポートにより、--posixPOSIXとさらに互換性があります。 sh.

sh=バッシュ?

長い間、ほとんどのGNU / Linuxシステムを/bin/sh指すために使用されてきました。/bin/bashその結果、両者の違いを無視することはほぼ安全です。しかし、最近になって変化が始まりました。

システムのいくつかの一般的な例/bin/sh/bin/bash一部は/bin/bash存在しない場合があります)は次のとおりです。

  1. sh最新のDebianとUbuntuシステムはへのデフォルトのシンボリックリンクですdash
  2. 忙しい箱、通常はLinuxシステムの起動時間の一部として実行されますinitramfsashシェルを使用して実装されます。
  3. BSDと通常Linux以外のシステム。 OpenBSD はpdkshKorn シェルの子孫を使用します。 FreeBSDはshもともとUNIX Bourneシェルの子孫です。 Solarisには独自のシステムがありますが、sh長い間POSIXと互換性がありませんでした。ガボプロジェクト

/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を探すそしてFreeBSDを探すそれをサポートしてください。

シェルボーンライン

最終的に「shebang」行を作成し、どちらを使用するかを決定します。

例えば

#!/bin/sh

sh(そしてそれが指すものは何でも)使用します。

#!/bin/bash

/bin/bash利用可能な場合に使用します。それ以外の場合は、エラーメッセージで失敗します。もちろん、次のような他の実装を指定することもできます。

#!/bin/dash

どちらを使うのか

私のスクリプトでは、sh次の理由でを好みます。

  • それは標準化されています
  • より簡単で習得が簡単です。
  • bashPOSIXシステム間で移植可能です。そうでない場合でもsh

bash使用すると利点もあります。その機能は、プログラミングをより便利にし、他の現代のプログラミング言語でプログラミングするのと似ています。これには、スコープ付きのローカル変数や配列などが含まれます。 Plainshは非常にミニマルなプログラミング言語です。

答え2

@Hunter.S.Thompsonの優れた答えに加えて、スクリプトの移植不可能な部分は次のとおりです。

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

これは${variable/search/replace}GNU拡張です。ただし、純粋なPOSIXを使用すると、これを簡単に回避できます。

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

ハンターに続いて、これはシェバンを次に変更するよりも優れた解決策です。#! /bin/bash

関連情報