Bashスクリプトのコマンドラインからスペースを含む入力を受け入れる方法

Bashスクリプトのコマンドラインからスペースを含む入力を受け入れる方法

現在、コマンドラインから入力を受け入れるbashスクリプトがありますが、入力にスペースがあり、bashスクリプトはスペースの後の単語を読みません。スクリプトはこれです

#!/bin/bash
var1=$1
var2=$2
echo $var1
echo $var2

このファイルをtest.shとして保存するとします。今私の入力は次のようになります。

./test.sh hi check1,hello world

出力は -

hi
check1,hello

しかし、出力が必要です。

hi
check,hello world

PS:二重引用符で入力を提供できないため、空白の単語を読むための別の解決策が必要です。

答え1

それは不可能です。パラメータの単語分割はスクリプトの実行前に発生するため、スクリプトの起動時にパラメータはすでに単語に分割されています。man bash詳しくは「単語分割」をご覧ください。

もしあなたなら知る2つのパラメータがあります。最初のパラメーターにはスペースは含まれません。何とか解決できます。

#! /bin/bash
first=$1
shift
rest="$*"

printf '<%s>\n' "$first" "$rest"

しかし、まだいくつかのスペースを1つに縮小します。

答え2

@chorobaが正しく指摘したように、少なくともデフォルトではこれを行うことはできません。

その理由は、シェルがタスクを実行する前に分析するコマンドラインでは、これは明確に定義されたいくつかの手順を実行するプロセスです。これらのステップの1つは「フィールド分割」です。ここで、シェルは入力行を複数の部分に分割します。考慮する:

コマンド引数1引数2

シェルは、「command」がコマンド、「arg1」が最初の引数、「arg2」が2番目の引数であるかどうかを判断する必要があります。そうではありませんか? 「arg1」が最初の引数で「arg1 arg2」でない理由、または「command」が「command arg1」でないコマンドである理由などが必要です。

いいえ、しかし、この分割の実行方法に影響を与える2つの要因があります。これは(シェル)変数IFSとOFSです。 IFS(「内部フィールド区切り記号」)は、マスクが解除されたときにフィールドを区切る文字のリストです。上記の例では、「arg1」は「arg2」と「command」とスペースで区切られています。これはIFSの一部です。

IFSは直接任意の文字(空の文字列を含む)に設定できますが、デフォルトでは(POSIX文書で指定されている)「空白」、「タブ」、「改行」に設定されています。詳細については、次を参照してください。IFSについて学ぶ

やや長い一般的な紹介の後、これはあなたの質問について何を意味しますか?

  1. IFSを操作してフィールド分割がどのように実行されるかに影響を与える可能性がありますが、次のことを行う必要があります。今後スクリプトが起動中です。例:

    % SAVIFS="$IFS" ;IFS エクスポート=""
     % /path/to/your/script arg1 arg2 ...
     %IFS="$SAVIFS"
  2. 独自の規則に従って、スクリプト内でフィールド分割を実行できます。これを行うにはキャプチャします。みんなパラメータを文字列に入れて直接分割します。

    /bin/bash#!/bin/bash
     chArgs="$*"
     引数1=""
     引数1=""
     [...]
     shoptの最後のチューブ
     #ここで$ chArgsの内容を分割します。たとえば、次のようになります。
     echo "$chArgs" IFS='' 読み取り arg1 arg2
     printf "%s\n%s\n" "$arg1" "$arg2"
    
     #またはどのように機能するかを示すために:
     echo "$chArgs" IFS=',' arg1 arg2 読み取り
     printf "%s\n%s\n" "$arg1" "$arg2"

ただし、文字列、特にIFSの文字を含むことができる文字列を処理するときは、常に正しい引用符に従う必要があります。あなたの例では:

#!/bin/bash
var1=$1
var2=$2
echo $var1
echo $var2

この正しい参照がないため、期待どおりに機能しない(追加)理由のようです。努力する:

#!/bin/bash
var1="$1"
var2="$2"
echo "$var1"
echo "$var2"

関連情報