
Ubuntu日本語フォーラム

ログインしていません。
Ubuntu初心者です
サスペンド(ハイバーネート)からの復帰時にコマンド、あるいはスクリプトを自動で実行させる方法はないでしょうか?
どなたか教えていただけたら幸いです
OS:Ubuntu10.10デスクトップ版
オフライン
詳細は理解しておりませんが、下記などが参考になるかと思います。
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/522998/comments/42
これはkernel moduleのxhci_hcdがロードされた状態だと、サスペンドに失敗するという不具合に対するワークアラウンドとして示されたものです。
/etc/pm/sleep.d/
以下に作成されたファイルの内容がサスペンド時や、復帰時に実行されるようです。
今回の場合だと、
if [ "$1" = "resume" ]
then
modprobe xhci_hcd
fiのような形で実行したいコマンドを指定しておけばよいのでは無いかと思います。
オフライン
お返事ありがとうございます
早速やってみたのですが、どうもうまくいきません
実はTeamViewerというソフトをサスペンドからの復帰時に終了させてから再起動させようと思って質問しました
手始めにサスペンド復帰時に実行できるかどうかを試すため、TeamViewerを終了してからサスペンドし、復帰させたのですが、TeamViewerは起動してくれませんでした
#!/bin/sh
if [ "$1" = "resume" ]
then
/opt/teamviewer/teamviewer/6/bin/teamviewer
fi
を/etc/pm/sleep.d/の9_teamというファイルに記述し、実行権を与えました
何か間違っているでしょうか?
オフライン
すみません。具体的なお話を先に確認するべきでした。
#2で書いた手順はシステム側で実行するものですので、ユーザ側のプログラムの制御には不向きかと思います。
もしかしたらsudoと組み合わせればできるかも知れませんが、sudoで指定するユーザがログイン中であるかのチェックなども含めるとちょっと面倒かもという気がします。
gnome側でご希望の動作をさせる方法があればよいのですが、残念ながら私は存じません。
どなたかご存知の方からコメントがつけばよいのですが。。
サスペンド/ハイバネート時にプログラムを終了させて、復帰時に再開させたいという理由が、いまいち想像できないのですが、背景の事情(問題となっている現象)などをご説明いただけると別のアプローチが考えられるかも知れません。
オフライン
TeamViewerという遠隔操作ソフトを使っているのですが、これがサスペンドに入り復帰したあとネットに接続できない状態になってしまうのです
こうなると一度閉じてから再起動させるしかないのですが、これでは遠隔操作の意味がありません
そこでこのような質問をいたしました
要は、TeamViewerが常にネットに繋がっている状態にするのが目的です
オフライン
http://www.teamviewer.com/ja/help/index.aspx
でしょうか。
うーん。接続が切れた場合に自動で再接続するように作られていれば良かったのですが、マニュアルをちょっと見た感じではそのような設定項目は無さそうな。。
# 逆にだからこそ復帰時にプログラムを再スタートさせたい、ということなのですよね。きっと。
もう一度探してみたのですが、やはりgnomeで復帰時に特定のコマンド、スクリプトを実行する方法は見つからず。。
なぜか上手くいかずに完成せずに終わっていますが、
http://ubuntuforums.org/showthread.php?t=1009045&page=4
などで似た様なことをやろうとしていたようです。
# 上記ではsudoでは無くsuを使っているようです。
何か良い方法はないかしら。
# すみません。どなたか良いアイデアあればご参加下さい。。
オフライン
# もうちょっと待った方がよいのかしら。。
# フォローが付かないので、ちょっと試してみたことを投稿します。
/etc/pm/sleep.d
はユーザ毎の設定には不向きと言いつつ、他にアイデアが浮かばなかったので、一案を。。
/etc/pm/sleep.d/20_launch-user-script
など適当な名前で/etc/pm/sleep.d以下にスクリプトを作ります(念のためchmodで755にしてあります)。
内容を下記のようにしてみました。
#!/bin/bash
case $1 in
hibernate|sleep)
for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq`
do
sleep_script=`finger -l $i | grep Directory | sed -e 's/Directory:\s\([\/a-zA-Z0-9]*\).*/\1\/.sleep/'`
if [ -f $sleep_script ]
then
sudo -H -u $i -- bash $sleep_script
fi
done
;;
resume|thaw)
for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq`
do
resume_script=`finger -l $i | grep Directory | sed -e 's/Directory:\s\([\/a-zA-Z0-9]*\).*/\1\/.resume/'`
if [ -f $resume_script ]
then
sudo -H -u $i -- bash $resume_script
fi
done
;;
esacちょっと試行錯誤したので冗長だったり不自然な点があるかも知れません。雰囲気だけ伝われば、ということで。
やりたいことは単純で、
1. ログインしているユーザの一覧を作る
2. ログインしているユーザのホームディレクトリを取得する
3. そのディレクトリの下にある特定のファイル名のスクリプトを実行する
もしwhoとかfingerとかが入っていなければ追加しないと上記のスクリプトは正常に動きません。bashやsedはデフォルトで入っていたはず。
スクリプトを実行したいユーザのホームに.resumeというファイルを作り(~/.resume)
#!/bin/bash env DISPLAY=:0.0 firefox &
とか書いておくとfirefoxが起動できたっぽいです。
もし上記を試す場合、十分な検証ができているとはとても言えないスクリプト、方法ですので、必要に応じてmanなどを参照しながら何をやろうとしているのか理解しながら試してみてください。
上記のスクリプトに限った話ではありませんが、基本的にはどこかに書いてあったスクリプトを、内容を理解せずにコピペして使うというのはセキュリティ意識という観点では非常に不味いことです。
悪意のあるスクリプトを拾ってきて問題を起こすということも有り得ますし、悪意は無い場合でもミスにより問題を起こす可能性もあります。
オフライン
hmatsue による投稿:
コード:
#!/bin/bash case $1 in hibernate|sleep) for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq` do sleep_script=`finger -l $i | grep Directory | sed -e 's/Directory:\s\([\/a-zA-Z0-9]*\).*/\1\/.sleep/'` if [ -f $sleep_script ] then sudo -H -u $i -- bash $sleep_script fi done ;; resume|thaw) for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq` do resume_script=`finger -l $i | grep Directory | sed -e 's/Directory:\s\([\/a-zA-Z0-9]*\).*/\1\/.resume/'` if [ -f $resume_script ] then sudo -H -u $i -- bash $resume_script fi done ;; esac
もしかしたら五十歩百歩なのかも知れませんが、ちょっとだけ修正。
#!/bin/bash
case $1 in
hibernate|sleep)
for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq`
do
sleep_script=`finger -l $i | grep Directory | sed -e 's/Directory: \([^ ]*\).*/\1\/.sleep/'`
if [ -f $sleep_script ]
then
sudo -H -u $i -- bash $sleep_script
fi
done
;;
resume|thaw)
for i in `who -q | head -n1 | sed -e 's/\s\+/\n/g' | sort | uniq`
do
resume_script=`finger -l $i | grep Directory | sed -e 's/Directory: \([^ ]*\).*/\1\/.resume/'`
if [ -f $resume_script ]
then
sudo -H -u $i -- bash $resume_script
fi
done
;;
esacUserの$HOMEを抜き出すにはこっちの方がマシかも。
# gnomeとかでありそうな機能のようにも思えるのだけど、やはり見つけられない。。
オフライン
#!/bin/bash
while :
do
xeyes
doneのスクリプトを実行すると,
killall で xeyes を終了させても無限ループで再度 xeyes が起動されます.
ukks さん による投稿:
実はTeamViewerというソフトをサスペンドからの復帰時に終了させてから再起動させようと思って質問しました
TeamViewer を上記のような無限ループの中に入れたスクリプトで起動し,
/etc/pm/sleep.d には TeamViewer を killall するようなスクリプト
#!/bin/sh
if [ "$1" = "resume" ]
then
killall teamviewer
fiを置くことで,お望みの状態にならないでしょうか?
当方で試した際は,上記スクリプトをGUIのダブルクリックで起動させ,
ログインセッションとは別のセッションからの操作を試すため,
敢えて他のマシンから ssh でログインして以下のコマンドを試しました.
$ pgrep xeyes # xeyes の PID の確認
6096
$ killall xeyes # xeyes にシグナルを送って終了させる.xeyes のウインドウが一度閉じてまた開く
$ pgrep xeyes # xeyes の PID が変わっていることを確認
7439
オフライン
宛 einundzwanzighundertsechsさん
ご参加、ありがとうございます。 :)
無限ループで呼び出すことでも対処できるのですね。これならスクリプトもシンプルになって良さそうです。
宛 ukksさん
einundzwanzighundertsechsさんがご紹介下さった方法を試す場合、プログラムの終了前に無限ループスクリプトをkillする必要があるかと思いますので、その点にだけ注意下さい。
例えばスクリプトの名前をteamviewer_loop.shなどとした場合、
pgrep teamviewer_loop.sh
などとしてプロセスID(PID)を調べ、
そのPIDに対してkillする必要があります。例えばPIDが1234であったとすると
kill 1234
といった具合です。
# なんとなくプログラムを終了させる必要は無さそうな使い方をされているような気がしますが、念の為。
オフライン
私が #9 に投稿したのは骨格だけなので,
タイミングの問題で TeamViewer がネットに接続できないようなら,
無限ループの中に sleep を入れるとか,
無限ループの中でネットの接続を確認してから teamviewer を起動するとか,
の工夫が必要になるかもしれません.
それと,本題とは無関係ですが,
hmatsue さん による投稿:
例えばスクリプトの名前をteamviewer_loop.shなどとした場合、
pgrep teamviewer_loop.sh
などとしてプロセスID(PID)を調べ、
そのPIDに対してkillする必要があります。例えばPIDが1234であったとすると
kill 1234
といった具合です。
まさにその動作をするコマンドが pkill です.
解説は pgrep の man ページに併記されています.
オフライン
お返事大変遅れて申し訳ありません
御二方どうもありがとうございます
結論から言いますとeinundzwanzighundertsechsさんのアドバイス通りでいいようなのですが、質問があります(hmatsueさんすいません、あんなにすごいスクリプトを書いていただいてとても嬉しいのですが、残念ながら当方の理解をはるかに超えています。今回はeinundzwanzighundertsechsさんのアドバイス通りにしようかと思います)
#!/bin/bash
while :
do
teamviewer
done
にてTeamViewerのループを確認したあと
#!/bin/sh
if [ "$1" = "resume" ]
then
killall TeamViewer.exe
fi
を/etc/pm/sleep.dに置き、復帰時に再起動することを確認しました
しかし、einundzwanzighundertsechsさんの予測通りネットワーク接続完了前に起動してしまい、意味が無くなってしまいます
そこで無限ループの中に30秒ほどsleepを入れたいのですが、
#!/bin/bash
while :
do
sleep 30 ; teamviewer
done
というような感じでいいのでしょうか?
あと関係ない話ですが、茶色の四角で囲ってある「コード:」とか、「xxxxxさん による投稿:」とか、茶色の四角だけってのはどうやっているのでしょうか?
このフォーラム自体まだ使い慣れていないので・・・・・
すいません・・・・
オフライン
シンプルな方法で目的が達成できるなら、それに越したことは無いので良いと思います。 :)
sleepを入れるだけならukksさんが書かれた方法で良いはずです。
もし興味があれば、pingとか使って工夫してみても面白いかもですね。
# それはシェルスクリプトに慣れてからでも良いと思いますが。
コード、とかhogehogeによる投稿、という囲みについては、投稿欄下のBBCodeのリンク先を参照下さい。
quoteタグについては、誰かの投稿の「引用」ボタンを押すことで自動的に挿入されます。
オフライン
私が思い描いていたのは,
初回起動時の待ち時間を 0 にするため,
sleep を後ろに置いた
#!/bin/bash
while :
do
teamviewer ; sleep 30
doneでした.
オフライン
なるほど。sleepを前に置くと、(復帰時ではない)初回の起動時に無駄に待たされてしまいますね。
復帰時の動作は前においても、後ろにおいても実質的な差は無いので後ろにおくのが良いですね。
# この辺が経験値とか想像力の差なのかなぁ。。 (^^;
オフライン
どうもありがとうございます
おかげで何ら問題なく動くようになりました
また何かありましたらその時はよろしくお願いします
本当にありがとうございました!
オフライン