シェルスクリプトを実行すると『そのようなファイルやディレクトリはありません』や『コマンドが見つかりません』と出る場合

[参考記事] cron実行時に『/bin/sh: 〜〜: command not found』と出てcronが実行されない場合

Windowsで作成したシェルスクリプト(シェルファイル)をUnix系OS、Linuxで実行したときに次のようなエラーが出る場合の対処法です。

そのようなファイルやディレクトリはありません
No such file or directory

コマンドが見つかりません
command not found

このとき改行コードが間違っていることが考えられます。
Windowsでは標準では改行コードはCR+LF、Unix・LinuxではLFです。
(CR:キャリッジリターン LF:ラインフィード)
[参考記事] 改行コードのCRとLF (キャリッジは印字ヘッドのことではありません)

例えば次のようなコード

#!/bin/sh

env

catコマンドで改行コードを含めて表示させて可視化します。

Linux(GNU)などでは『-A』オプション

$ cat -A test.sh
#!/bin/sh^M$
^M$
env^M$
記号意味
^MCR(¥r)
$LF(¥n)

FreeBSD(BSD)などでは『-e』オプション

$ cat -e test.sh
#!/bin/sh^M^J
^M^J
env^M^J
記号意味
^MCR(¥r)
^JLF(¥n)

このようにCR(^M)が表示されていた場合には改行コードが間違っています。

コマンドでテキストファイルからCRを削除するには次のようにします。

$ tr -d '¥r' test.sh

なぜ『そのようなファイルやディレクトリはありません』や『コマンドが見つかりません』のようなエラーが出るかというと改行コードのCRが余ってしまうからです。

#!/bin/sh¥r¥n
¥r¥n
env¥r¥n

これがLinuxなどでは

#!/bin/sh¥r[改行]
¥r[改行]
env¥r[改行]

と判断され、
『#!/bin/sh』としたコードが『#!/bin/sh¥r』
『env』としたコードが『env¥r』
と解釈されるからです。

MacOS9で作成されたファイルなどで改行コードがCRのみだった場合には次のように解釈され、すべてがコメントとして扱われます。

#!/bin/sh¥r¥renv¥r

このためこのシェルファイルを実行しても何も表示されず、何も起こりません。

ファイル転送時に改行コードを自動で変換する方法

改行コードのトラブルを事前に防ぐにはファイル転送時にASCIIモードを使用することで、改行コードが自動で変換されます。
転送ソフトには拡張子で判断して、テキストファイルであればASCIIモード、画像などのファイルであればバイナリモードを自動的に選択してくれる機能があります。

FFFTP

[参考記事] FFFTP

ツールバーから
『A』ボタンを押すとすべてのファイルがASCIIモードの転送
『B』ボタンを押すとすべてのファイルがバイナリモードの転送
『AB』ボタンを押すとすべてのファイル名による自動モード切替の転送


ファイル名の設定は
オプション→環境設定


『転送1』タブ内にあります。

WinSCP

[参考記事] WinSCP

オプション→環境設定


『転送』カテゴリ内にあります。

デフォルトでASCIIモードの転送になるのは次のパターンです。

*.*html; *.htm; *.txt; *.php; *.php3; *.cgi; *.c; *.cpp; *.h; *.pas; *.bas; *.tex; *.pl; .htaccess; *.xtml; *.css; *.cfg; *.ini; *.sh; *.xml

ファイルを転送した後に拡張子を変更した場合や、そもそも拡張子がない場合には自動判別の条件から外れるので注意が必要です。

FTPコマンドでもASCIIモード、バイナリモードの設定はできます。

関連記事

スポンサーリンク

push

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る