1. ホーム
  2. bash

[解決済み] WindowsのバッチとLinuxのBashの両方で実行できるスクリプトは?

2022-11-11 18:06:10

質問

Windows (batとして扱われます) と Linux (Bashで) の両方で実行されるスクリプトファイルを1つ書くことは可能でしょうか?

私は両方の基本的な構文を知っていますが、分かりませんでした。おそらく、Bash の不明瞭な構文または Windows のバッチ プロセッサのグリッチを悪用することができます。

実行するコマンドは、他のスクリプトを実行するための単なる1行かもしれません。

動機は、WindowsとLinuxの両方で単一のアプリケーション起動コマンドを持つことです。

更新しました。 システムのネイティブシェルスクリプトの必要性は、正しいインタプリタのバージョンを選択し、特定のよく知られた環境変数などに適合する必要があることです。CygWinのような追加環境のインストールは好ましくないので、quot;download &&run" のコンセプトを維持したいです。

Windows で考慮すべき唯一の言語は Windows Scripting Host - WSH で、これは 98 以降デフォルトで設定されています。

どのように解決するのですか?

私が行ったことは cmd の label 構文をコメントマーカーとして使用します。 . ラベルの文字であるコロン ( : ) と同じです。 true と同じです。もし、ラベル文字の直後に GOTO で使用できない別の文字が続く場合、あなたの cmd スクリプトに影響を与えないようにする必要があります。 cmd のコードに影響を与えることはありません。

ハックは、文字列の後にコードの行を置くことです " :; ". もしあなたがほとんどワンライナーのスクリプトを書いているのなら、あるいはそうかもしれませんが、1行で書けるのは sh の多くの行に対して cmd を使用する場合は、次のようにするとよいでしょう。忘れてはならないのは $? は次のコロンの前でなければならないことを忘れないでください。 : というのは : リセット $? を 0 にリセットします。

:; echo "Hi, I’m ${SHELL}."; exit $?
@ECHO OFF
ECHO I'm %COMSPEC%

ガードするための非常に巧妙な例 $? :

:; false; ret=$?
:; [ ${ret} = 0 ] || { echo "Program failed with code ${ret}." >&2; exit 1; }
:; exit
ECHO CMD code.

を読み飛ばすためのもう一つのアイデア cmd のコードをスキップするためのもう一つの方法は ヘルドックス ということで shcmd のコードは未使用の文字列として扱われ cmd はそれを解釈します。この場合、heredoc のデリミタが引用符で囲まれていることを確認します (これは sh で実行されたときに、その内容に対して何らかの解釈をすることを防ぐためです。 sh で実行される場合、その内容は解釈されません)。 : ということは cmd で始まる他の行と同じように、それをスキップして : .

:; echo "I am ${SHELL}"
:<<"::CMDLITERAL"
ECHO I am %COMSPEC%
::CMDLITERAL
:; echo "And ${SHELL} is back!"
:; exit
ECHO And back to %COMSPEC%

ニーズやコーディングスタイルによっては、インターレースで cmdsh のコードは意味をなすかもしれませんし、そうでないかもしれません。heredocsを使うことは、このようなインターレーシングを行うための一つの方法です。しかし、これは GOTO 技術 :

:<<"::CMDLITERAL"
@ECHO OFF
GOTO :CMDSCRIPT
::CMDLITERAL

echo "I can write free-form ${SHELL} now!"
if :; then
  echo "This makes conditional constructs so much easier because"
  echo "they can now span multiple lines."
fi
exit $?

:CMDSCRIPT
ECHO Welcome to %COMSPEC%

ユニバーサルコメントは、もちろん、文字列の : # または :;# . スペースやセミコロンが必要なのは sh# は、識別子の最初の文字でない場合は、コマンド名の一部と見なします。例えば、ファイルの最初の行にユニバーサルコメントを書いてから GOTO メソッドを使ってコードを分割する前に、ファイルの最初の行にユニバーサルコメントを書きたいと思うかもしれません。そうすれば、なぜあなたのスクリプトがそのように奇妙に書かれているのかを読者に知らせることができます。

: # This is a special script which intermixes both sh
: # and cmd code. It is written this way because it is
: # used in system() shell-outs directly in otherwise
: # portable code. See https://stackoverflow.com/questions/17510688
: # for details.
:; echo "This is ${SHELL}"; exit
@ECHO OFF
ECHO This is %COMSPEC%

このように、いくつかのアイデアと達成するための方法 shcmd -との互換性のあるスクリプトを、私の知る限り深刻な副作用なしに(しかも cmd を出力することなく '#' is not recognized as an internal or external command, operable program or batch file. ).