「No such file or directory」なのにファイルがある時の原因
この記事で解決できること
lsで見えているのにNo such file or directoryが出る原因を切り分けられます- ファイル名の不可視文字・CRLF・壊れたシンボリックリンク・動的リンカ欠落を見分けられます
- 「実体はあるのにアクセスできない」状態を、コマンドで確実に特定して直せます
結論(最短の切り分け)
「あるのに無い」と言われる原因はだいたい次の 4 つです。
- ファイル名に見えない文字が混入 →
ls -bで可視化 - スクリプトの shebang が CRLF / 誤パス →
cat -Aで行末確認 - シンボリックリンクのリンク先が消えている →
ls -laで赤表示・readlink -f - 実行バイナリの動的リンカ(ELF interpreter)が無い →
fileで形式確認
まず ls -b(不可視文字)と ls -la(リンク切れ)の 2 つを見れば 8 割は切り分きます。
前提(対象環境)
- OS:Ubuntu / Debian 系を想定(他ディストリでも考え方は同じ)
- シェル:bash
- 例では対象を
target/./run等の名前で示します
なぜファイルがあるのに「No such file or directory」が出るのか?
結論: 多くは「あなたが見ているファイル名」と「カーネルが探しているパス文字列」が一致していないか、ファイルの実体(リンク先・インタプリタ)が欠けているためです。
ls の表示は人間向けに整形されており、末尾の空白や制御文字、リンク切れの状態までは一目で分かりません。一方 open() / stat() といったシステムコールはパス文字列を 1 バイトも違わず照合します。つまり画面上は同じに見えても、実際のバイト列が違えば ENOENT(No such file or directory)が返ります。
このエラーは大きく 2 系統に分かれます。
- パス文字列の不一致型:名前に不可視文字、相対パスのずれ、CRLF 混入
- 実体欠落型:シンボリックリンクのリンク先消失、実行バイナリの動的リンカ欠落
以降、頻度順に切り分けていきます。
原因1: ファイル名に見えない文字が混入している
結論:
ls -bでファイル名をエスケープ表示し、末尾スペース・タブ・全角空白などの不可視文字を炙り出します。
コピー&ペーストやスクリプト生成で、ファイル名の末尾に半角スペースや改行、全角スペース( )が混入することがあります。見た目は target でも実体は target (末尾スペース付き)なら、cat target は当然 No such file or directory になります。
ls -b
target\
末尾に \ (バックスラッシュ+スペース)が見えれば、名前に空白が含まれている証拠です。タブは \t、全角空白は \343\200\200 のように 8 進数で表示されます。
確実に対象を指定するには、補完(Tab キー)を使うか、find で実バイト列を拾ってリネームします。
find . -maxdepth 1 -name 'target*' -print mv -i 'target ' target
迷ったら ls | cat -A も有効です。cat -A は行末を $ で示すため、ファイル名末尾の余分な空白が $ の手前に見えます。
原因2: スクリプトの shebang が CRLF / 誤パスになっている
結論:
./script.sh: No such file or directoryで本体は存在する場合、shebang 行の CRLF 改行か、存在しないインタプリタパスを疑います。
./deploy.sh を実行して No such file or directory が出るのに ls -l deploy.sh では確かに存在する——これは典型的な shebang 問題です。Windows で編集したファイルは行末が CRLF(\r\n)になり、#!/bin/bash が #!/bin/bash\r と解釈されます。カーネルは /bin/bash\r というパスのインタプリタを探して失敗します。
cat -A deploy.sh | head -1
#!/bin/bash^M$
行末に ^M(CR)が見えれば CRLF 確定です。sed か dos2unix で除去します。
sed -i 's/\r$//' deploy.sh
shebang のパス自体が間違っているケースもあります(例:#!/usr/local/bin/python だが実体は /usr/bin/python3)。head -1 でパスを確認し、command -v で実在を照合します。
head -1 deploy.sh command -v python3
詳しい手順は 「bad interpreter」エラーの直し方 を参照してください。
原因3: シンボリックリンクのリンク先が消えている
結論: リンク自体は
lsに出ても、リンク先が消えた dangling symlink はアクセス時にNo such file or directoryを返します。ls -laの色表示とreadlink -fで確認します。
シンボリックリンクは「別のパスへの参照」です。参照先が削除・移動されると、リンクファイル自体は残ったまま中身だけが消えます。ls には名前が出るのに開けない、という状態の典型です。
ls -la target
lrwxrwxrwx 1 user user 18 Jun 6 10:00 target -> /opt/app/current/bin
カラー表示の端末では壊れたリンクが赤く点滅・反転表示されます。リンク先の実在は readlink -f(最終的な実体パスを解決)と、その結果への ls で確認します。
readlink -f target ls -la "$(readlink -f target)"
リンク先の ls が No such file or directory を返せば、リンク切れ確定です。リンクを張り直すか、正しい実体を復旧します。
ln -sfn /opt/app/releases/2026-06-06/bin target
cp file target のようにリンク経由で書き込もうとすると、リンク先のディレクトリが無い場合に cannot create ... No such file or directory となります。エラーがリンク先を指していないか必ず確認してください。
原因4: 実行バイナリの動的リンカ(ELF interpreter)が無い
結論: コンパイル済みバイナリで
./run: No such file or directoryが出る場合、ファイル自体ではなく、それが要求する動的リンカ(ld-linux)や ABI が無いことが原因です。fileで形式を確認します。
ELF 実行ファイルは、起動時に「動的リンカ」というローダーを必要とします。バイナリのアーキテクチャ(32bit/64bit、arm/x86)がホストと異なる、または必要な動的リンカが存在しないと、カーネルはローダーを No such file or directory として拒否します。混乱しやすいのは、存在しないのはバイナリ本体ではなくローダーである点です。
file ./run
./run: ELF 32-bit LSB executable, Intel 80386, dynamically linked, interpreter /lib/ld-linux.so.2, ...
interpreter /lib/ld-linux.so.2 が指すローダーがホストに無ければ起動できません。要求するローダーの実在を確認します。
ls -l /lib/ld-linux.so.2
64bit ホストで 32bit バイナリを動かす場合は 32bit ランタイムを導入します。
sudo dpkg --add-architecture i386 sudo apt update && sudo apt install libc6:i386
arm 用バイナリを x86 で実行しようとした、といったアーキテクチャ不一致なら、そもそも実行できません。file の出力でホストの uname -m と一致するか確認してください。
原因5: パスの途中や相対パスがずれている
結論: 末端ファイルではなく、パスの途中ディレクトリが欠けている / 入れない場合も
No such file or directoryになります。namei -lで経路を 1 段ずつ追跡します。
/opt/app/data/config.yml を開けないとき、欠けているのは config.yml とは限りません。途中の data ディレクトリが存在しない、あるいはリンク切れの可能性があります。namei -l はパスを root から順に解決し、どこで失敗したかを示します。
namei -l /opt/app/data/config.yml
f: /opt/app/data/config.yml drwxr-xr-x root root / drwxr-xr-x root root opt drwxr-xr-x root root app ENOENT - - data
ENOENT が出た段(この例では data)が原因箇所です。
相対パスのずれも頻出です。cd した先が想定と違えば、同じ ./config.yml でも別の場所を指します。pwd で現在地を確認し、迷ったら絶対パスで指定します。
pwd cat /opt/app/data/config.yml
クォート内のチルダは展開されません。cat "~/notes.txt" はホームではなくカレントの ~/notes.txt を探して失敗します。cat ~/notes.txt(クォートなし)か cat "$HOME/notes.txt" を使ってください。