spaceなどお行儀の悪い文字がPATHに含まれている場合の対処

シングルクォートとダブルクォートの挙動の違い

公開日: 2022-01-02
更新日: 2023-08-10

  Table of Contents

お行儀の悪いPATH

Problem

1
2
3
4
% mkdir -p './sandbox/hop step/heisei jamp'
% touch './sandbox/hop step/heisei jamp'/README.md
% ls './sandbox/hop step/heisei jamp'         
README.md

という形で誤ってスペースを含めたディレクトリを作成してしまったとします. hop stepを含む以下のディレクトリを消す場合どのようなコマンドが考えられるか?

このような場合,

  • エスケープ \ をスペースの前に加える
  • シングルクオート '' で文字を囲み, シェルに1つの文字列として認識させる

という対応策が考えられます.

1
2
3
4
5
6
7
# with escape
% rm -rf ./sandbox/hop\ step 

# with single quotes
% rm -rf './sandbox/hop step'
% rm -rf ./sandbox/'hop step'
% rm -rf .'/sandbox/hop step'

お行儀の悪いファイル名はどれくらいあるのか?

簡易的に, findコマンドで確かめてみます

1
2
% find ~ -name "*[ \[\(\<\;\&\|\"\{\~\|]*"  -type f | wc -l
5137

結構あることがわかります. 簡単に確認してみると, snap経由でいれたfirefoxや.venv内部にある Pythonパッケージの中やGoogle-Chromeなどの設定ファイルの中にある傾向でした.

1
2
3
4
5
6
7
8
% find ~ -name "*[ ]*"  -type f | wc -l 
267

% find ~ -name "*[\{]*"  -type f | wc -l
4866

% find ~ -name "*[\~]*"  -type f | wc -l
4

シングルクォートとダブルクォートの差異

クォートは特定の文字列をリテラルとして使用する機能がありますが、各クォートで処理が異なる場合があります. 感覚的な話になりますが, 以下のような区分があります.

シングルクォート 強いクォート
ダブルクォート 弱いクォート
1
2
3
4
5
6
7
8
9
10
11
## 環境変数の出力
% echo $PWD
/home/hogehoge/Desktop/

## 環境変数をダブルクォートで囲んで出力
% echo "$PWD"
/home/hogehoge/Desktop/

## 環境変数をシングルクォートで囲んで出力
% echo '$PWD'
$PWD

上記の例ではダブルクォートでは変数が展開される一方, シングルクォートにおいては変数が展開されないという違いが確認できます. これは各クォートでエスケープできるメタキャラクタが異なるのが理由です.

Column: クォートとメタキャラクタ

クォート種類 エスケープしないメタキャラクタ
シングルクォート シングルクォートの中にシングルクォートは入れられない
ダブルクォート $, バッククォート, ダブルクォート, \, !

date

1
2
3
4
5
## 
% echo "today: $(date)"
today: Thu Aug 24 02:45:42 PM JST 2021


References



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)