BIN_DIR =“〜/ bin /”のスクリプトでmkdirが失敗する(そのようなファイルやディレクトリがない)のはなぜですか?


10

mkdirコマンドが「そのようなファイルまたはディレクトリはありません」で失敗するのはなぜですか?

#!/bin/bash

set -e

BIN_DIR="~/bin/"

if [ ! -d "$BIN_DIR" ]; then
  mkdir "$BIN_DIR"
fi

回答:


11

~Zannaの回答で説明されているように、チルダが引用されているため、エラーメッセージが生成されます。を使用する場合~、スクリプトの関連部分は次のようになります。

BIN_DIR=~/bin/

以下のためならばどんな理由あなたは、文字列を引用したい、あなたは環境変数を使用することができます$HOME

BIN_DIR="$HOME/bin/"

私の意見では、2番目のアプローチはより良い実践です。


6
~スクリプトでの使用に問題はありません。コマンドラインとまったく同じように機能します。問題は、Zannaの回答で説明されているように、引用によってチルドの展開がブロックされることです。
terdon 2017年

@terdon、同意する。しかし、私は何かが間違っているとは言いませんでしたが、注意を払うべきではないので、それはより良い考えです。
pa4080 2017年

5
ただし、ここではコマンドラインとスクリプトの間に違いはありません。これがスクリプト内にあるという事実はまったく無関係であり、コマンドラインでもまったく同じエラーが発生します。問題は引用であり、スクリプト内にあるわけではありません。
terdon 2017年

それは完全に本当です$HOMEが、スクリプトで使用することも良い考えです。
デザート

3
@ pa4080 チルド展開を使用するよりも展開する方が良いと思う理由の説明を追加できます$HOMEか?あなたが与えた唯一の説明は、「あなたはあまり注意を払うべきではないので、それはより良い考えです」と言うことです。どういう意味かわかりません。編集でそれについて説明できますか?それがなければ、あなたの答えを裏付けるものは何もないので、確かにそれはそれに属しています。チルダ展開はのためにPOSIXによって要求されてきた今、かなり長い間 スクリプトのhashbangラインがあり#!/bin/bash、私は移植性が理由ではないと仮定して。
Eliah Kagan 2017

23

~引用されているため機能しません。二重引用符 "チルド展開を抑制します。リテラル名のディレクトリはありません~/binman bash(強調鉱山)で説明されているように:

チルダ拡張

単語が引用符で囲まれていないチルダ文字( `〜 ')で始まる場合、最初の引用符で囲まれていないスラッシュの前のすべての文字(または引用符で囲まれていないスラッシュがない場合はすべての文字)は、チルダ接頭辞と見なされます。チルダ接頭辞の文字が引用符で囲まれていない場合、チルダに続くチルダ接頭辞の文字は、可能なログイン名として扱われます。このログイン名がnull文字列の場合、チルダはシェルパラメータHOMEの値に置き換えられます。HOMEが設定されていない場合、シェルを実行しているユーザーのホームディレクトリが代わりに使用されます。それ以外の場合、チルダプレフィックスは、指定されたログイン名に関連付けられたホームディレクトリに置き換えられます。

あなたは引用符を削除することができているので、~パス内の唯一の文字である~/binシェル拡張を行うことになります、と私たちは、この場合の拡大を求めています。シェル、少なくともBash 4ではチルダ拡張の結果に対してそれ以上の拡張を実行しませ。これは、Ubuntuの現在のリリースまたは最近のすべてのリリースにあります。したがって、ホームディレクトリにスペースなどの通常とは異なる文字が含まれていても問題ありません。

または$HOME~、の代わり使用できます。これは、パラメーターの展開が二重引用符によって抑制されず、単一引用符によってのみ抑制されるためです。二重引用符、展開された値自体がそれ以上展開されないようにするため、単語の分割ファイル名の展開は行われません。だから、$HOME限り、あなたが二重引用符を保つよう、あまりにも奇妙な名前のホームディレクトリで動作します。


このステートメントによれば、「パラメーターの展開は二重引用符によって抑制されず、単一引用符によってのみ抑制されます」:の出力はcd '~'です-bash: cd: ~: No such file or directory
pa4080 2017年

2
@ pa4080の展開は~パラメータ展開の一部ではありません。
Barmar 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.