Bashスクリプトはファイル名(または相対パス)を文字列として受け取りますが、そのファイルから読み取る必要があります。スクリプト内で直接リテラルとして宣言する場合(引用符なし)にのみファイル名から読み取ることができます...これは暗黙的に文字列であるため、引数には不可能です。観察する:
a="~/test.txt"
#Look for it
if [[ -a $a ]] ; then
echo "A Found it"
else
echo "A Error"
fi
#Try to use it
while read line; do
echo $line
done < $a
b='~/test.txt'
#Look for it
if [[ -a $b ]] ; then
echo "B Found it"
else
echo "B Error"
fi
#Try to use it
while read line; do
echo $line
done < $b
c=~/test.txt
#Look for it
if [[ -a $c ]] ; then
echo "C Found it"
else
echo "C Error"
fi
#Try to use it
while read line; do
echo $line
done < $c
YIELDS:
A Error
./test.sh: line 10: ~/test.txt: No such file or directory
B Error
./test: line 12: ~/test.txt: No such file or directory
C Found it
Hello
上記のように、上記のルーチンにコマンドライン引数を渡すことはできません。引用符で囲まれた文字列と同じ動作をするからです。
これは、~
- expansionのルールの一部です。 ~
が引用されている場合、この拡張は実行されないことがBashマニュアルに明確に記載されています。
~
を引用しないでください。
file=~/path/to/file
ファイル名の残りを引用する必要がある場合:
file=~/"path with spaces/to/file"
(これは、園芸品種のシェルでは完全に合法です。)
$HOME
の代わりに~
を使用します。
file="$HOME/path/to/file"
シェル変数のタイプについて少し混乱しているようです。
すべてが文字列です。
沈み込むまで繰り返します:すべてが文字列です。(整数を除きますが、ほとんどの場合、文字列の上でのハックです。配列。ただし、文字列の配列。)
これは"foo"
というシェル文字列です。 "42"
も同様です。 42
も同様です。 foo
も同様です。物事を引用する必要がない場合は、そうしないのが合理的です。誰が"ls" "-la" "some/dir"
と入力したいですか?