私はスクリプト機能に固執します。豊富なインタラクティブ機能(コマンドライン版、補完、プロンプトなど)は非常に異なる傾向があり、まったく互換性のない方法で同様の効果を実現します。zshにはどの機能があり、bashにはありませんか、またはその逆ですか?インタラクティブな使用に関するいくつかの指針を示します。
bashに最も近いものは、ATT ksh93またはmksh(Kornシェルとクローン)です。Zshには機能のサブセットもありますが、zshネイティブモードではなく、kshエミュレーションモードで実行する必要があります。
POSIX機能(最近のsh
シェルで使用可能)や、比較的あいまいな機能、または前述のインタラクティブな使用のための機能はリストしません。観察は、Debian wheezyにあるbash 4.2、ksh 93u、およびmksh 40.9.20120630の時点で有効です。
$'…'
(バックスラッシュ補間を使用したリテラル文字列)は、ksh93およびmkshで使用できます。`$"… "(翻訳された文字列)はbash固有です。
Mkshとksh93はステートメントで;&
失敗する必要case
がありますが;;&
、後続のケースをテストする必要はありません。Mkshは;|
そのために持っており、最近のmkshは;;&
互換性を考慮しています。
((…))
算術式と[[ … ]]
テストはksh機能です。一部の条件演算子は異なります。以下の「条件式」を参照してください。
Kshとbashには両方ともコプロセスがありますが、動作は異なります。
Mkshとksh93 function name {…}
は、標準に加えて関数定義の構文をサポートしますname () {…}
がfunction
、kshで使用するとスコープルールが変更さname () …
れるため、互換性を維持するようにしてください。関数名に使用できる文字の規則はさまざまです。英数字にこだわる_
。
Ksh93とmkshはブレース拡張をサポートしてい{foo,bar}
ます。Ksh93は数値範囲をサポートしていますが{1..42}
、mkshはサポートしていません。
ksh93とmkshサポート部分文字列での抽出${VAR:offset}
と${VAR:offset:length}
ではなく、ケースのような折りたたみは${VAR^}
、${VAR,}
などあなたはと小文字の変換を行うことができますtypeset -l
し、typeset -u
bashのとkshの両方に。
彼らはとの交換をサポートします${VAR/PATTERN/STRING}
か${VAR/PATTERN//STRING}
。STRINGの引用規則は少し異なるため、STRINGでバックスラッシュ(および他の文字)を避けます(変数を作成し${VAR/PATTERN/$REPLACEMENT}
、置換に引用文字が含まれている場合は代わりに使用します)。
アレイの拡張(${ARRAY[KEY]}
、"${ARRAY[@]}"
、${#ARRAY[@]}
、${!ARRAY[@]}
kshの中のようなbashで)仕事。
${!VAR}
is ${OTHERVAR}
の値(間接変数参照)がbash固有である場合に拡張されます(kshはとは異なる何かを行います)。kshでこの二重拡張を取得するには、代わりに名前参照()を使用する必要があります。同じように動作します。VAR
OTHERVAR
${!VAR}
typeset -n VAR=OTHERVAR; echo "$VAR"
${!PREFIX*}
プロセス置換<(…)
と>(…)
は、ksh93ではなくmkshでサポートされています。
shopt -s extglob
bashでアクティブ化する必要があるksh拡張globパターンは、ksh93とmkshで常に使用できます。
Mkshはのような文字クラスをサポートしていません[[:alpha:]]
。
Bashとksh93は疑似ファイルとを定義しますが、mkshは定義しません。/dev/tcp/HOST/PORT
/dev/udp/HOST/PORT
スクリプト内のリダイレクトでワイルドカードを展開すること(そのファイル名がパターンに唯一一致var="*.txt"; echo hello >$a
するa.txt
場合の書き込みの場合など)は、bash固有の機能です(他のシェルはスクリプトでそれを行いません)。
<<<
here-stringsは、bashのようにkshで機能します。
>&
構文エラーをリダイレクトするショートカットもmkshではサポートされていますが、ksh93ではサポートされていません。
[[ … ]]
二重括弧構文
kshからの二重ブラケット構文は、bashと同様に、ATT ksh93とmkshの両方でサポートされています。
ファイル演算子
ksh93、mkshとbashのサポートなど、POSIXに同じ拡張子、-a
旧式の同義語として-e
、-k
(粘着性)、-G
(EGIDが所有している)、-O
(EUIDによって所有者)、 -ef
(同じファイル)、 -nt
(より新しい)、 -ot
(より古いです)。
-N FILE
(最後の読み取り以降に変更された)は、mkshではサポートされていません。
Mkshには正規表現一致演算子はありません=~
。Ksh93にはこの演算子があり、bashと同じマッチングを実行BASH_REMATCH
しますが、一致したグループを後で取得するための同等の機能はありません。
文字列演算子
Ksh93とmkshは、同じ文字列比較演算子<
をサポートし、>
bash およびの==
同義語としてもサポートしています=
。Mkshはロケール設定を使用して辞書式順序を決定せず、文字列をバイト文字列として比較します。
その他のオペレーター
-v VAR
変数が定義されているかどうかをテストするには、bash固有です。どのPOSIXシェルでも、を使用できます[ -z "${VAR+1}" ]
。
エイリアス名で使用できる文字のセットは、すべてのシェルで同じではありません。関数と同じだと思います(上記参照)。
Ksh93にはと呼ばれる組み込み関数がありますが、組み込みbuiltin
コマンドとして名前を実行しません。command
エイリアスと関数をバイパスするために使用します。ビルトインが存在する場合はこれを呼び出し、そうでない場合は外部コマンドを呼び出します(これはで回避できますPATH= command error_out_if_this_is_not_a_builtin
)。
これはbash固有です。.sh.fun
、.sh.file
および.sh.lineno
ksh93 でも同様の効果を得ることができます。mkshにはついにありLINENO
ます。
declare
kshのbash固有の名前ですtypeset
。使用typeset
:bashでも機能します。
Mkshはのlocal
エイリアスとして定義されていtypeset
ます。ksh93では、使用するtypeset
(またはエイリアスを定義する)必要があります。
Mkshには連想配列がありません(まだリリースされていないバージョンが予定されています)。
typeset -t
kshにはbash (トレース関数)とまったく同じものはないと思います。
Ksh93にはありません-e
。
Ksh93とmksh は、bash -e
と-n
同様におよびオプションを処理します。Mkshもを理解し-E
、ksh93はそれをオプションとして扱いません。バックスラッシュ展開は、ksh93ではデフォルトでオフになり、mkshではデフォルトでオンになります。
Kshは組み込みコマンドを無効にする方法を提供していません。組み込みを回避するには、外部コマンドのパスを調べて明示的に呼び出します。
Ksh93は持って-a
いますが、持っていません-l
。Mkshにはどちらもありません。
ksh93もmkshも持っていませんexport -n
。typeset +x foo
代わりに使用してください。bashとkshで動作します。
Kshは環境を介して関数をエクスポートしません。
let
bashとkshで同じです。
これはbash固有の機能です。while read
ループまたはコマンド置換を使用してファイルを読み取り、それを行の配列に分割できます。世話をしIFS
、グロビングします。これは以下と同等ですmapfile -t lines </path/to/file
:
IFS=$'\n'; set -f
lines=($(</path/to/file))
unset IFS; set +f
printf
非常に似ています。ksh93はbashのフォーマットディレクティブをすべてサポートしていると思います。mkshは%q
またはをサポートしていません%(DATE_FORMAT)T
。一部のインストールでprintf
は、mksh組み込みではなく、代わりに外部コマンドを呼び出します。
printf -v VAR
bash固有であり、kshは常に標準出力に出力します。
readlineに関するすべてのオプションを含む、いくつかのオプションはbash固有です。オプションには-r
、-d
、-n
、-N
、-t
、-u
bashの、は、ksh93とmkshで同一です。
同じ構文で、Ksh93とmkshで変数を読み取り専用として宣言できます。変数が配列の場合は、最初に割り当てる必要があり、次にで読み取り専用にしreadonly VAR
ます。kshでは関数を読み取り専用にすることはできません。
すべてのオプションset
とは、set -o
POSIXまたはksh機能です。
shopt
bash固有です。とにかく多くのオプションはインタラクティブな使用に関するものです。一部のオプションによって有効になるグロビングおよびその他の機能への影響については、以下の「オプション」のセクションを参照してください。
こののバリアントは.
kshにも存在します。bashとmkshでは、のsource
後PATH
に現在のディレクトリを検索しますが、ksh93では、とまったく同じです.
。
DEBUG
擬似信号はmkshに実装されていません。ksh93では、情報を報告する別の方法で存在します。詳細については、マニュアルを参照してください。
kshでは、はのtype
エイリアスですwhence -v
。mkshではtype -p
、実行可能ファイルへのパスではなく、人間が読めるメッセージを出力します。whence -p COMMAND
代わりに使用する必要があります。
オプション
dotglob
ksh93 のオプションをエミュレートするには、を設定できますFIGNORE='@(.|..)'
。mkshにはこのようなものはないと思います。
このextglob
オプションは、kshでは事実上常にオンです。
これはmkshにもksh93にも存在しないと思います。これはzshで実行されます(null_glob
またはcsh_null_glob
設定されていない場合のデフォルトの動作)。
Ksh93には、で再帰的なグロビングがあり**/
、で有効になっていset -G
ます。Mkshには再帰的なグロビングはありません。
Ksh93は常に親シェルでパイプラインの最後のコマンドを実行します。これはbashではlastpipe
オプションを設定する必要があります。Mkshは常にパイプラインの最後のコマンドをサブシェルで実行します。
shopt -s nocaseglob
、shopt -s nocasematch
—大文字と小文字を区別しないパターン
Mkshには、大文字と小文字を区別しないパターンマッチングはありません。Ksh93はパターンごとにこれをサポートし~(i)
ます。パターンの前にを付けます。
Mkshにはこれがありません。Ksh93はパターンごとにこれをサポートし~(N)
ます。パターンの前にを付けます。
明らかに、ほとんどのBASH_xxx
変数はkshに存在しません。$BASHPID
高価ですがポータブルsh -c 'echo $PPID'
でエミュレートでき、最近mkshに追加されました。ksh93にしてmkshに。ksh93に。BASH_LINE
.sh.lineno
LINENO
BASH_SUBSHELL
.sh.subshell
Mkshとksh93はどちらもENV
、起動時に指定されたファイルを提供します。
EUID
そしてUID
ksh93には存在しません。MkshはそれらUSER_ID
を呼び出しますKSH_UID
。ありませんGROUPS
。
FUNCNAME
そしてFUNCNEST
kshには存在しません。Ksh93にはとが.sh.fun
あり.sh.level
ます。function foo { …; }
(括弧なし!)で宣言された関数は、で独自の名前を持ってい$0
ます。
GLOBIGNORE
ksh93に存在しますが、名前と構文が異なります。これはと呼ばれFIGNORE
、コロンで区切られたリストではなく単一のパターンです。@(…|…)
パターンを使用します。KshはFIGNORE
bashを包含し、構文はまったく異なります。
Ksh93とmkshにはHOSTTYPE
、MACHTYPE
やのようなものはありませんOSTYPE
。またSHELLOPTS
かTIMEFORMAT
。
MkshにはPIPESTATUS
ありますが、ksh93にはありません。
Mkshとksh93にはがありRANDOM
ます。