0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

find で見つけたファイルを sudo 経由で実行する

Last updated at Posted at 2020-03-28

find で見つけたファイルを sudo で実行する

実際の想定シナリオ

yocto で raspberry-pi 用に toolchain をビルドしたときに ./tmp/deploy/sdk のディレクトリに以下のようなファイル名で、(バイナリ形式の) shell script が生成される。

poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh

このスクリプトを実行すると /opt/poky/2.7.2 以下に必要なツールチェーンがインストールされる。

課題

  1. poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh は実行したときに確認を求められる

  2. poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh というファイル名は条件によって変わるかもしれないので、パスを決め打ちして実行したくない。find で見つけて実行したい。

  3. poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh/opt/poky/2.7.2 を書き換えるので root 権限が必要だから、sudo 経由で実行する必要がある。通常 sudo を実行する際は、対話形式でパスワードを要求される。

解決方法 (答え)

PASSWORD=xxxxx
find ./tmp/deploy/sdk -name *.sh | xargs -n 1 -I "{}" sh -c "echo ${PASSWORD} | sudo -S {} -y"

解説

poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh のオプション

-y オプションを指定することで y を押したと判断してユーザーに確認を求めない。

sh ./tmp/deploy/sdk/poky-glibc-x86_64-core-image-full-cmdline-cortexa7t2hf-neon-vfpv4-raspberrypi4-toolchain-2.7.2.sh -y

これは確認を求めるプログラムでよくある話です。

find コマンド

find の引数にフォルダ名を指定して -name *.sh のパターンを指定することで 指定したフォルダ以下にある sh ファイルを標準出力に出力する

find ./tmp/deploy/sdk -name *.sh

xargs コマンド

find の出力をパイプでつないで、xargs コマンドに渡すことで find の結果に基づいてコマンドを実行することができる。

xargs コマンドは通常パイプで渡されたデータを一気に起動するコマンドに渡す。
ところが今回実行したいのは shell script なので -n 1 を指定することで find の出力一行に対してコマンドをひとつずつ実行する。

sudo コマンドの-S オプション (標準入力からパスワードを読み込む指定)

sudo 経由で実行する必要がある。
sudo には -S というパスワードを標準入力から取得するためのオプションがある。

これを使って 実行ユーザーのパスワードを標準入力から与えて sudo に渡す。

echo ${PASSWORD} | sudo -S ./hogehoge.sh param1

xargs コマンドの-I オプション (プレースホルダの指定)

xargs のコマンドでパイプを含むコマンドを実行する必要がある。

xargs には -I というプレースホルダを指定するオプションがある。

例えば以下のようにすれば -I に渡した {} が動的にパイプで渡された文字列に置き換えられて実行される。

find ./tmp/deploy/sdk -name *.sh | xargs -I {} cp {} {}.bak

xargs コマンドでパイプを含むコマンドを実行

Usage: xargs [OPTION]... COMMAND [INITIAL-ARGS]...

xargs コマンドはオプション指定が終わった後の最初の単語を実行すべきコマンドと認識する。
このためパイプを含む文字列をダブルクォート等で囲んで COMMAND の部分に指定できないので
COMMAND の部分には sh を指定する。

sh -c を指定することでパラメータで指定したコマンドを実行できる。

これまでの内容をまとめると、最終的なコマンドは以下のようになる。

find ./tmp/deploy/sdk -name *.sh | xargs -n 1 -I "{}" sh -c "echo ${PASSWORD} | sudo -S {} -y"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?