「No such file or directory」なのにファイルがある時の原因

「No such file or directory」なのにファイルがある時の原因

この記事で解決できること

  • ls で見えているのに No such file or directory が出る原因を切り分けられます
  • ファイル名の不可視文字・CRLF・壊れたシンボリックリンク・動的リンカ欠落を見分けられます
  • 「実体はあるのにアクセスできない」状態を、コマンドで確実に特定して直せます

結論(最短の切り分け)

「あるのに無い」と言われる原因はだいたい次の 4 つです。

  1. ファイル名に見えない文字が混入ls -b で可視化
  2. スクリプトの shebang が CRLF / 誤パスcat -A で行末確認
  3. シンボリックリンクのリンク先が消えているls -la で赤表示・readlink -f
  4. 実行バイナリの動的リンカ(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 確定です。seddos2unix で除去します。

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」エラーの直し方 を参照してください。

結論: リンク自体は 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)"

リンク先の lsNo 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" を使ってください。

まとめ:上から順に試すチェックリスト

「あるのに無い」と言われたら、次の順で潰します。

  • ls -b target — ファイル名の不可視文字を可視化(原因1
  • cat -A script.sh | head -1 — shebang の CRLF / 行末を確認(原因2
  • ls -la target / readlink -f target — シンボリックリンク切れを確認(原因3
  • file ./run — 動的リンカ・アーキテクチャを確認(原因4
  • namei -l /path/to/file — パスのどの段で落ちるか追跡(原因5

関連記事も合わせてどうぞ。