質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

3回答

9508閲覧

シェル実行時cpコマンドが完了しない

NickName

総合スコア7

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

1グッド

0クリップ

投稿2017/01/06 15:59

編集2017/01/07 16:57

###前提・実現したいこと
raspberry pi 3 を利用して下記のようなシステムを構築しようとしております。
1.SDカード挿入時に/etc/udev/rules.dを利用して、2.のスクリプトが実行される
2.スクリプトの中でSDカードの中身を特定のディレクトリにコピー
3.ファイルリネームプログラム(JAVA:自作)呼び出し

###発生している問題・エラーメッセージ
コピーコマンド後の処理が実行されない。
ファイル自体はコピーされていて、直前までのechoも出力されているが、cpコマンド後のechoは出力なし。

###該当のソースコード

bash

1#!/bin/bash 2 3# DEVNAME=/dev/sdc1 4JAVA_DIR=/mnt/data/Systems/Scripts/RecordOrganizer/ 5JAVA_CLASS=ExifRename 6MOUNT_DIRECTORY=/mnt/tmp/ 7TARGET_DIRECTORY=/mnt/data/Share/Temp/targets/ 8OUTPUT_DIRECTORY=/mnt/data/Share/Albam/ 9 10TO1_MAIL=user1@example.com 11TO2_MAIL=user2@example.com 12MSG_BACKUP_S="バックアップを開始しました" 13MSG_BACKUP_N="バックアップ可能なメディアではありませんでした" 14MSG_BACKUP_E="バックアップを完了しました" 15LOGF_PATH=/mnt/data/Share/Temp/targets/sdCopy.log 16RENAME_LOG=/mnt/data/Share/Temp/targets/rename.log 17 18echo `date` 0=$0 1=$1 DEVNAME=$DEVNAME > $LOGF_PATH 19echo dev_check! >> $LOGF_PATH 20 21if [[ "$DEVNAME" =~ sd[c-z][0-9] ]]; then 22 echo $MSG_BACKUP_S | mail -s "data backup" $TO1_MAIL $TO2_MAIL 23else 24 # echo $MSG_BACKUP_N | mail -s "data backup" $TO1_MAIL $TO2_MAIL 25 exit 1 26fi 27 28echo "backup start!!" >> $LOGF_PATH 29 30mount $DEVNAME $MOUNT_DIRECTORY >> $LOGF_PATH 31 32\cp -rf $MOUNT_DIRECTORY $TARGET_DIRECTORY 33 34echo "backup finish!!" >> $LOGF_PATH 35 36cat $LOGF_PATH | mail -s "finish backup" $TO1_MAIL $TO2_MAIL 37 38umount $MOUNT_DIRECTORY >> $LOGF_PATH 39 40cd $JAVA_DIR 41java $JAVA_CLASS $TARGET_DIRECTORY $OUTPUT_DIRECTORY "exiftool" 42 43cat $RENAME_LOG | mail -s "Finish Rename!!" $TO1_MAIL $TO2_MAIL

1.から呼び出された場合のログ(sdCopy.log)

Sat 7 Jan 01:45:02 JST 2017 0=/mnt/data/Systems/Scripts/sdcard_sync.sh 1= DEVNAME=/dev/sdc1 dev_check! backup start!!

->finish backupのメールなし

2.のスクリプトを自分で実行した場合のログ(sdCopy.log)

Sun 8 Jan 01:27:06 JST 2017 0=/mnt/data/Systems/Scripts/sdcard_sync.sh 1= DEVNAME=/dev/sdc1 dev_check! backup start!! backup finish!!

->finish backupのメールあり

###試したこと
2.のスクリプトを自分で実行した場合は、コピー、リネームともに成功するが、
1.の機能から呼び出された場合にコピーコマンドが完了しない。

1.の機能から呼び出されたあと、時間をおいて(10分ぐらい)
2.のスクリプトを呼び出すと下記のような標準出力がある。(もう一度呼び出すと出力なし)

mount: /dev/sdc1 is already mounted or /mnt/tmp busy /dev/sdc1 is already mounted on /mnt/tmp

※これは1.の機能から呼び出されたときにcpで止まっているので、umountされていないため
出てるエラーとして無視していました。

###補足情報(言語/FW/ツール等のバージョンなど)
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 8.0 (jessie)
Release: 8.0
Codename: jessie

Linux関連初心者の為、至らぬ点など多々あるかと存じますが、
ご指導いただけましたら幸いです。

指摘がありました、cpの前についているバックスラッシュですが、
cpにエイリアスが掛けられていた場合(cp で cd -iなどのなっている場合があるらしい)の対応として、とりあえず入れてみた。な状態です。
外してもつけても挙動に変更がなかったため、つけたままになっておりました。

また、1.から呼び出されたスクリプトが生存しているか確認したいのですが、現在確認方法がわかっておらず、確認できていない状態です。

yodel👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

せめてログファイルくらい貼り付けられた方がよろしいのではないでしょうか?

cp直前のバックスラッシュが気になりますが・・・

投稿2017/01/07 16:01

....

総合スコア102

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NickName

2017/01/07 16:58

ご指摘ありがとうございます。 ログの内容追加とcpの前のバックスラッシュに関して記述させていただきました。
....

2017/01/07 17:23

狙い通りにスクリプトが動作しない時はとりあえず以下のような点を調べられると手掛かりが得られやすいと思います。 ・手動と自動実行それぞれのprintenv(またはset)結果を比較してみる。 ・手動と自動実行それぞれのid(またはwhoami)結果を比較してみる。 ・mountが成功しているかログに出力してみる。 ・mountされたファイルシステムのパーミッションを確認してみる。 ・ログにPIDも出力してpsで生存確認できるようにしておく。 ・ログ出力を常に追記(またはloggerでsyslogdへ送る)にしてコンソールを複数開き、1つのコンソールでtail -fでログ出力がリアルタイムに見れるようにしておき、他のコンソールでmountとかpsとかを発行できる準備にして、SDカードを挿抜しつつ同時並行で確認を進める。(logger+syslogdならudevのログも一緒に見ることになるのでいいかも) ・各コマンドの終了コードもいちいちログに出力して意味ありげな値を返していたらmanかinfoを熟読
....

2017/01/08 03:18

あと、違う手法として、 ・そもそもmountせずddでリッピングすることによってSDカードのアクセスを極力少なくてハードウエア依存のオーバーヘッドを抑え、リッピングしたイメージファイルをループバックmountして中身を取り出す。 ・素のmountを使わずautofsを経由することにして、mount、umount周辺の面倒な処理はautofsに任せてしまう といった別案も検討できるのではないでしょうか。 UNIX OSの何でもかんでもファイルシステムに抽象化してしまうというポリシーは上位処理がシンプルになるので小気味良いポリシーだとは思いますが、ハードウェア依存部は泥臭い処理の塊でタイムラグとかタイミングとかロックだとかいった不条理な特性を完全に消し去る事はできず、それらがmountなどの処理で現れますので、それをうまく回避するような工夫が必要だと思います。
NickName

2017/01/10 16:00

アドバイス誠にありがとうございます。 確認が遅くなりまして申し訳ありません。 環境変数など確認しながら動作を確認していった結果、処理時間によって強制終了されているような動きであることが判明しました。 コピーするデータの多さによって、コピー中に終了したり、リネーム作業中に終了していたりしました。 詳細は内容を修正致します。
....

2017/01/10 16:51

メモリー不足でOSにぶっ殺されている可能性もありますね。 Linuxをはじめ最近のOSは仮想記憶で物理メモリより大きなメモリ空間を扱う事ができますが、本当に不足してくるとOSがプロセスに対して無差別殺戮を始めます。一般にOOM-Killerと呼ばれるメカニズムです。 トカゲのシッポ切り同様、ユーザプロセスを殺してkernel等の重要なプロセスを守ってOS中心部の安定性を維持しようとします。RaspberryPiはワークステーションやサーバのような一般的なLinuxプラットフォームに比べればカスの様な容量のメモリしか積んでいませんから可能性はあります。 私も詳しく無いので「OOM-Killer」でググってもらうのが早道だと思いますが、cpがメモリを食い過ぎていると仮定して、 cp -rf $MOUNT_DIRECTORY $TARGET_DIRECTORY & echo $! >> $LOGF_PATH wait などのようにしてcpのプロセスIDをログファイルに出力しておき、別ターミナルでtopを実行してそのプロセスIDの負荷状況を見守るとか、cat /proc/プロセスID/status でVmという接頭辞が付いた項目からプロセスの消費量を見守るとかいったデバッグも、もしかしたら有効かもしれません。 あと、ちょっと別の視点でcpではなくrsyncのような大量ファイルコピーに向いたコマンドに変えてみるとか。 rsync -av --delete $MOUNT_DIRECTORY $TARGET_DIRECTORY ちなみに上記は-vオプション(冗長な進行レポート)を指定しているのでログには大量にメッセージが出ると思いますが、うまくいく事がわかったら-vオプションは無くてもいいでしょう。
NickName

2017/01/11 15:50

ご返答ありがとうございます。 /var/log/messages を確認してみましたが、OOM-Killerは動作しておりませんでした。 スクリプト実行中に殺されるケースを調べてみようと思います。
guest

0

根本的な考え方が間違えていたようで、問題は別の点にあるようです。

bash

1hoge=0 2while : 3do 4 sleep 1; echo `date` >> $LOGF_PATH 5 if [ $hoge -gt 3000 ] ; then 6 echo "over 3000" >> $LOGF_PATH 7 break 8 fi 9done

というスクリプトに置き換えた所、30秒ほどで強制終了されていることが判明しました。
別の質問として改めて建てさせていただきます。

投稿2017/01/12 13:42

NickName

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

....

2017/01/12 15:10

試しに「udev timeout」でググってみたら似たような話題が沢山出てきましたよ。 どうやらudevが制限時間を設けているようです。 解決方法として、udevからはatへスクリプトを登録するだけにして、実際の実行はatからやってもらうという手が以下のサイト(ご本家ですね)で紹介されていました。 http://unix.stackexchange.com/a/28711/27578
NickName

2017/01/13 10:12

「"/etc/udev/rules.d" タイムアウト」でググって迷子になっておりました。 具体的なページのご提示まで、本当に有難うございます!! こちらのコメントにベストアンサーをつけたいのですが、システム上できないようですので、別の....さんのコメントにつけさせていただきます!
guest

0

aliasでオプションを付けられていることがあるので、cpコマンドをフルパスで記載してはいかがですか。whichでフルパスを確認すればパスが分かります。

bash

1[root@hogehoge ~]# which cp 2alias cp='cp -i' 3 /bin/cp ←これが本体 4----------------------------------------------------- 5## こんな風に書き直す 6/bin/cp -rf $MOUNT_DIRECTORY $TARGET_DIRECTORY

投稿2017/01/12 06:04

mosapride

総合スコア1480

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NickName

2017/01/12 13:31

確認してみましたが、動作に影響はなかったみたいです。 アドバイスありがとうございました。
fumiyas

2020/12/16 03:47

`bash` はスクリプト (非対話モード) で実行したときにはエイリアス設定には従いません。なので関係ありません。 ```console $ bash -c 'alias foo="echo bar"; foo' bash: 行 1: foo: コマンドが見つかりません ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問