zshで実行すると、Bashスクリプトが「無効な下付き文字の範囲に割り当てられている」をスローします。

zshで実行すると、Bashスクリプトが「無効な下付き文字の範囲に割り当てられている」をスローします。

修正する これを見てください協会、0ではなく1で始まるように配列添字を更新しましたが、配列変数が正しく読み取られたようです。

#!/bin/bash

#Root folders for Git update.
    ROOT[1]="/Users/ayusman/dev/repos1"
    ROOT[2]="/Users/ayusman/dev/repos2"

#do some things with the ROOT variable.

ところで、先に宣言したシェル関数が認識されず、他の場所でエラーが見え始めました。

コマンドが見つかりません:git

だから一般的な質問は次のとおりです。

bashシェルで完全に機能するシェルスクリプトをzshシェルに移植するにはどうすればよいですか?

最近、MacをmacOS Catalina 10.15.2にアップグレードしました。

私のシェルスクリプトの1つは次のとおりです。

#!/bin/bash

#Root folders for Git update.
    ROOT[0]="/Users/ayusman/dev/repos1"
    ROOT[1]="/Users/ayusman/dev/repos2"

#do some things with the ROOT variable.

私のデフォルトのシェルがbashシェルだったとき、これはうまくいきました。ここで私がしたことは、シェルスクリプトで使用する配列変数にいくつかのフォルダを追加することです。アップグレードをリリースしてデフォルトのシェルをzshに設定した後、スクリプトを起動すると(.zsrcファイルのエイリアスを介して)、次のエラーが発生します。

[ayusman@~10:39AM]$updateExpediaGitRepos 
/Users/ayusman/scripts/updateGitRepos.sh:250: ROOT: assignment to invalid subscript range
[ayusman@~10:39AM]$

シェルを再びbashに変更したとき(下記のようにchshを実行して)、同じスクリプトが期待どおりに実行されることを確認しました。

chsh -s /bin/bash

したがって、基本的に質問は既存のbashスクリプトを使用せずにzshシェルで実行できますか?

ありがとう、アユシュマン

答え1

zshスクリプトの説明を要求しているようです。あなたはupdateExpediaGitReposそれが何であるかを言わなかったが、私は考えた。alias 源泉このスクリプトは、.またはsource組み込みコマンドを使用します。このコマンドは現在シェルソルバーにファイルのコードを解釈するように指示するため、shebang(#! /bin/bash)は関係ありません。 Shebang は、試している場合にのみカーネルで使用されます。実装するスクリプト。

おそらく、これはupdateGitRepos.shユーザーシェルのプロパティ(環境変数の設定、関数定義、エイリアス定義など)を変更してユーザーエクスペリエンスをカスタマイズするために使用されます。これは実行には役立ちません。

bash2つの異なる互換性のない言語の通訳者ですzsh(どちらもBourneシェル、Kornシェル、Cシェルから多くのインスピレーションを得ているため共通です)。通常、ある人が他の人のために書かれたコードを解釈できると期待することはできません。

特に、配列は非常に異なる方法で実装されます。

zsh配列は、実際にシェルで一般的に使用される他のほとんどのシェルやツールと同様に、インデックスが1から始まる配列です(詳細については、以下を参照してください)。Zsh配列の最初の要素にインデックスがゼロではなく1の理由がありますか?)。

bash配列は Korn シェルからコピーされます。これはスパース配列(正の整数に制限されたキーを持つ連想配列に似ています)であり、インデックスは0から始まります。

zsh複数のサポートシミュレーション他のシェル用に書かれたコードを解釈するために使用できます。特に、bash配列を使用してスクリプトを解析するのに便利なkshエミュレーションモードがあります。

emulate ksh

始めてください。

または:

emulate ksh -c 'some code'

このシミュレーションモードでコードを評価します。このモードで宣言された関数はシミュレーションモードを継承します。

さらに、kshシミュレーションモードではこのKSH_ARRAYSオプションがオンになっているため、配列インデックスは0から始まりますが、まだ希薄ではありません。

したがって、ここでエイリアスを変更して、次のように試すことができます。

emulate ksh -c '. /Users/ayusman/scripts/updateGitRepos.sh'

変える

. /Users/ayusman/scripts/updateGitRepos.sh

あなたの場合は、これで十分でも十分ではありません。このシミュレーションモードのみ改善する互換性のため、kshzsh を ksh レプリカにしません。そしてkshはbashではありません。

ユーザーのシェルをソースとして使用するには、サポートされているupdateGitRepos.sh各シェルごとに適切な言語で書かれた異なるバージョンのスクリプトを提供するか、サポートされているすべてのシェルと互換性のある構文を使用する必要があります。通常、配列は除外されます。 (しかし参照アレイのテストシェルのサポート可能な方法)。

スクリプトがユーザーの対話型シェルによって解釈されず、単に実行される場合は、shebangの/path/to/the/scriptおかげでスクリプトを実行すると、正しいソルバーが起動して解釈できます。 not source /path/to/the/script、not zsh /path/to/the/scriptbash /path/to/the/scriptここでも次のように動作します。これはbashスクリプトです(誤解を招く.sh拡張にもかかわらず))。

答え2

この動作は、zshシェルで配列がどのように機能するかによって発生し、その配列の索引付けは1いいえ存在する0。したがって、インデックスの要素にアクセスすると、0現在見ているエラーが発生します。

zshマニュアルで -15.2.1 配列添字

15.2.1 Array Subscripts

下付き文字を使用して、配列の個々の要素を選択できます。フォームの添え字は[exp]単一の要素を選択しますexp。ここではexp、まるで囲まれているかのように算術的に拡張されます$((...))。要素番号は次から始まります。1KSH_ARRAYSこのオプションが設定されていない場合、0から番号が付けられます。

このオプションが設定されていない場合、デフォルトはKSH_ARRAYS下付き文字を使用して配列要素にアクセスすることです。0 と評価し、空の文字列を返します。、しかしこれらの要素に書き込む試みはエラーとして扱われます。。以前のバージョンとの互換性のために、KSH_ZERO_SUBSCRIPT下付き文字の値0と1が同じになるようにこのオプションを設定できます。オプション説明のオプション説明を参照してください。

したがって、indexで始まる配列の動作をシミュレートするには、0スクリプトの上部でこのオプションを設定します。

setopt ksh_arrays

zshshe-bangインタプリタがに設定されていても、スクリプトが動作を示す理由を明確にするために、スクリプトは明示的な呼び出しで実行できます。#!/bin/bashこのzsh <script>場合、オペレーティングシステムはスクリプトの上部にあるインタプリタ行を認識しません。スクリプト自体が実行可能(chmod +x)で実行されると、./<script>スクリプトの上部に提供されているインタプリタが適用されます。

関連情報