こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

シェルでftp接続によるファイル取得について

以下のようなシェルスクリプトを作成しましたが、
(file-name) get: No such file or directory
(file-name) done: No such file or directory
のエラーメッセージが出てしまい、うまくいきません。
OSはLinux(FedoraCore4)です。
どうやらファイル名の取得がうまくいかず、エラーになっている
様です。
試しに直接ファイル名を指定して書くと、無事ファイルを
取得できます。

エラーの原因がお分かりになる方、どうぞ宜しくお願い致します。



-----------------------------------------------
#!/bin/sh

cd /local_test/log/
ftp -n xxx.xxx.xxx.xxx<< _EOF
user test_user test_pass
cd /test/log/
ascii
prompt

for i in *.log
do
chmod u+r $i
get $i
chmod u-r $i
done
bye
_EOF
exit 0
-----------------------------------------------

投稿日時 - 2007-03-19 14:17:34

QNo.2846631

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは、ham_kamoです。
ls *.logの結果で、ls -l と同じ表示が出てしまいましたか。
環境によって違うものなのですね。私が以前に使用していたサーバではファイル名一覧だけ出てきたのですが。
No.3の方が書いている
quote site chmod u+r *.log
という書き方も、そのサーバではエラーになっていました。(なのでややこしいスクリプトを書いたしだいなのですが)
もしお使いのサーバでは、上の書き方でエラーがならないのであれば、No.3の方の回答で済むと思います。

一応、それがエラーになってしまうから、という前提で、スクリプトに手を修正しました。さらにワンクッション置いて、ファイル名だけを抜き出して取得するようにしてみました。(テンポラリファイルがまた1つ増えました。。。)

以下のスクリプトで試してみていただけますか?

#!/bin/sh

cd /local_test/log/
tmpfile=/tmp/ftptmp.$$
tmpfile2=/tmp/ftptmp2.$$
tmpfile3=/tmp/ftptmp3.$$
tmpfile4=/tmp/ftptmp4.$$

cat > $tmpfile << _EOF
user test_user test_pass
cd /test/log/
ascii
prompt
_EOF

cp $tmpfile $tmpfile2
cat >> $tmpfile2 << _EOF
ls *.log
bye
_EOF

ftp -n xxx.xxx.xxx.xxx < $tmpfile2 | grep .log | grep -v '*.log' > $tmpfile3
awk '{print $NF}' $tmpfile3 > $tmpfile4

for i in `cat $tmpfile4`
do
cat >> $tmpfile << _EOF
quote site chmod u+r $i
get $i
quote site chmod u-r $i
_EOF
done

echo "bye" >> $tmpfile

ftp -n xxx.xxx.xxx.xxx < $tmpfile
rm $tmpfile $tmpfile2 $tmpfile3 $tmpfile4
exit 0

投稿日時 - 2007-03-22 10:10:36

お礼

すごい!!出来ましたよ!!
本当にありがとうございました。。。
何度も何度も質問してしまって本当に申し訳なかったです。

ham_kamoさんのお陰で完了することが出来ました。
見ず知らずの私にこんなにも丁寧に教えて頂いて、感謝の気持ちでいっぱいです。
本当に本当にありがとうございました。

投稿日時 - 2007-03-22 13:17:17

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

>やりたい事は、リモート先の指定フォルダ内にある"*.log"ファイルを

quote site chmod が効くようなので、

cd /local_test/log/
ftp -n xxx.xxx.xxx.xxx<< _EOF
user test_user test_pass
cd /test/log/
ascii
prompt
quote site chmod u+r *.log
mget *.log
quote site chmod u-r *.log
_EOF

投稿日時 - 2007-03-21 01:23:13

補足

ご回答ありがとうございました。

またまた説明不足だったのですが、リモート先で
chmod での「*」使用が禁止されているのです。
(セキュリティ上の問題らしいです)

説明不足で申し訳ありませんでした。

投稿日時 - 2007-03-22 11:28:48

ANo.2

No.1です。

> ローカルにある同名ファイルは取得できるのですが、無いものが取得できません

そうですね、ローカルのシェルスクリプトでファイルをgetするコマンドのスクリプトを作っているので、ローカルにあるファイルしか一覧に出ないですね。

chmodがなければ、
mget *.log
で一発なのですが、chmodが入るから、この手は使えません。
quote site chmod u+r *.log
という書き方もできないので。

と言うことで、ftpを2回にわけて行い、1回目はファイルリストを取得し、そのリストを元にftpのコマンドファイルを作成し、2回目に実際にgetするスクリプトに変えてみました。

#!/bin/sh

cd /local_test/log/
tmpfile=/tmp/ftptmp.$$
tmpfile2=/tmp/ftptmp2.$$
tmpfile3=/tmp/ftptmp3.$$

cat > $tmpfile << _EOF
user test_user test_pass
cd /test/log/
ascii
prompt
_EOF

cp $tmpfile $tmpfile2
cat >> $tmpfile2 << _EOF
ls *.log
bye
_EOF

ftp -n xxx.xxx.xxx.xxx < $tmpfile2 | grep .log | grep -v '*.log' > $tmpfile3

for i in `cat $tmpfile3`
do
cat >> $tmpfile << _EOF
quote site chmod u+r $i
get $i
quote site chmod u-r $i
_EOF
done

echo "bye" >> $tmpfile

ftp -n xxx.xxx.xxx.xxx < $tmpfile
rm $tmpfile $tmpfile2 $tmpfile3
exit 0

ただ、私の手元にテストできる環境がないので、実際に動くかどうかの確認はしていません。もしエラーが出た、うまく動かないなどの場合は、できるだけ詳しく(エラーメッセージなど)補足をお願いします。

投稿日時 - 2007-03-20 15:12:37

補足

度々のご回答本当にありがとうございました。

早速職場で試してみた所、ファイルは無事取得できるようになったのですが、エラーメッセージが出ていました。

--w--w--w-: No such file or directory
--w--w--w-: No such file or directory
--w--w--w-: No such file or directory
(以下続く。。。)

$tmpfile3を削除せずに、このファイルを開いてみたら

--w--w--w- 1 test web 1213 Mar 6 16:52 200502.log

となっていたので、どうやら文字の区切りごとにファイル名として実行しているようでした。

後はファイル名だけを取得するようにすれば良いのですが。。。
すみません、もう少し教えて頂けると助かりますので
宜しくお願い致します。

投稿日時 - 2007-03-22 09:38:07

ANo.1

問題点は2つあります。

まず、

ftp -n xxx.xxx.xxx.xxx<< _EOF
から
_EOF
の間には、FTPサーバに渡されるコマンドを記述しないといけません。その中に、
for in *.log
do
とFTPサーバが解釈できないシェルスクリプトが入っているので、エラーになります。

それからもう1つは、chmodです。これは、ローカルのファイルの属性を変更したいのか、リモートのファイルの属性を変更したいのか、どちらなのでしょうか。

ローカルのファイルの属性を変更したいのであれば、この chmod はFTPサーバで解釈されるので、うまくいきません。

リモートのファイルの属性を変更したいのであれば、FTPサーバではシェルとは少し書き方が違い、
chmod u+r $i
と同じことをFTPで行いたいときは、
quote site chmod u+r $i
と書かないといけません。

どちらにしても、正常に実行はされないはずです。

以上をまとめると、複数のファイルをまとめてFTPで扱うのであれば、いったん処理コマンドをテンポラリのファイルに書き出して、それを読み込ませたらいいのではないでしょうか。

一応、そのように書き直してみましたが、実際には動作確認していないので、エラーが出たらすみません。

#!/bin/sh

cd /local_test/log/
tmpfile=/tmp/ftptmp.$$

cat > $tmpfile << _EOF
user test_user test_pass
cd /test/log/
ascii
prompt
_EOF

for i in *.log
do
cat >> $tmpfile << _EOF
quote site chmod u+r $i
get $i
quote site chmod u-r $i
_EOF
done

echo "bye" >> $tmpfile

ftp -n xxx.xxx.xxx.xxx < $tmpfile
rm $tmpfile
exit 0

なお、このスクリプトでは chmod はリモートのファイルの属性を変更すると仮定して書いてますが、これがもしローカルのファイルの場合は、
quote site chmod u+r $i
quote site chmod u-r $i
を、それぞれ
!chmod u+r $i
!chmod u-r $i
に書き換えてください。(!はFTPでローカルコマンドを実行する記号です)

投稿日時 - 2007-03-19 14:54:37

お礼

説明が足りなくて申し訳ありませんでした。。。

>それからもう1つは、chmodです。これは、ローカルのファイルの属性を変更したいのか、リモートのファイルの属性を変更したいのか、どちらなのでしょうか。

お察しの通り、リモートファイルになります。
やりたい事は、リモート先の指定フォルダ内にある"*.log"ファイルを
全てローカルへダウンロードしたいのです。

教えて頂いたとおりに書いてみたところ、ローカルにある同名ファイルは取得できるのですが、無いものが取得できません。。。
修正してみたのですが、うまく動作せずで。。。申し訳ありません、もしお分かりになるようでしたら、再度ご教授頂けると助かります。
宜しくお願い致します。

投稿日時 - 2007-03-20 09:55:42

あなたにオススメの質問