とらりもん - shell scriptをPythonに任せる Diff
- Added parts are displayed like this.
- Deleted parts are displayed
like this.
2016/10/13 Jin Katagi 書きかけです
{{toc_here}}
! 動機づけ
シェルスクリプトはLinuxで仕事・研究をする上で必要不可欠です。
ちょっとしたコマンドをまとめておいたり、繰り返し処理が必用なバッチ処理をする時に重宝します。
しかしながら沢山シェルスクリプトを書いていると、段々と以下の点が気になってきます。
* 文法が直感的でない
* 文法の制限が厳しい
* 複雑な処理をすると読みづらい
!! 文法が直感的でない
パターンマッチ(${var%%.txt}, ${var#.txt})、条件判定(-eq, -ne -e) が、
一般的なプログラミング言語のもの(!=, =<)と比較して読みづらく感じます。
!! 文法の制限が厳しい
私が頭を悩ませたshのエラーを挙げます。
# NG : [] の前後にスペースを入れないとダメ
if [ -e test.txt]; then ....
# OK :
if [ -e test.txt ]; then ...
# NG : ヒアドキュメントの最後には空スペースを入れてはならない
cat << EOF > new.txt
test
EOF□ ←□の箇所に半角スペースが入っているとエラーになります
# OK :
cat << EOF > new.txt
test
EOF
!! 複雑な処理をすると読みづらい
これは書き手の問題があるかもしれませんが、複雑な処理をしようとすると段々読みづらくなってきます。
パイプに慣れてくると読みづらい処理を書きがちです。
以下の例はもう少し簡潔に書けますが(例えばsedの置換部分をdoの後に持っていったり、シェルスクリプトのパターンマッチを用いるなど)、極端な例として挙げておきます。
for file in `ls -1 datasets | xargs -I {} basename / | sed 's/*_\(.\).txt/\1.txt/g' | ....... `; do
このようなシェルスクリプトは書き終えた時は満足感にひたるのですが、後日メンテナンスや処理を書き換えようと思うと頭が痛いものです。
! Pythonでバッチ処理を書いてみる
その前に…
*シェルスクリプトの文法チェッカー([[ShellCheck|https://github.com/koalaman/shellcheck]])は入れていますか?
ここからは実際に自分が書いたシェルスクリプトをPythonで書き換えていきます。
Pythonは3.x系を想定しています。
!! subprocess
! Pythonでバッチ処理を書くことのデメリット
!! 2.X系、3.X系の互換性
! シェルスクリプト or Python のベストプラクティス
! まとめ
{{toc_here}}
! 動機づけ
シェルスクリプトはLinuxで仕事・研究をする上で必要不可欠です。
ちょっとしたコマンドをまとめておいたり、繰り返し処理が必用なバッチ処理をする時に重宝します。
しかしながら沢山シェルスクリプトを書いていると、段々と以下の点が気になってきます。
* 文法が直感的でない
* 文法の制限が厳しい
* 複雑な処理をすると読みづらい
!! 文法が直感的でない
パターンマッチ(${var%%.txt}, ${var#.txt})、条件判定(-eq, -ne -e) が、
一般的なプログラミング言語のもの(!=, =<)と比較して読みづらく感じます。
!! 文法の制限が厳しい
私が頭を悩ませたshのエラーを挙げます。
# NG : [] の前後にスペースを入れないとダメ
if [ -e test.txt]; then ....
# OK :
if [ -e test.txt ]; then ...
# NG : ヒアドキュメントの最後には空スペースを入れてはならない
cat << EOF > new.txt
test
EOF□ ←□の箇所に半角スペースが入っているとエラーになります
# OK :
cat << EOF > new.txt
test
EOF
!! 複雑な処理をすると読みづらい
これは書き手の問題があるかもしれませんが、複雑な処理をしようとすると段々読みづらくなってきます。
パイプに慣れてくると読みづらい処理を書きがちです。
以下の例はもう少し簡潔に書けますが(例えばsedの置換部分をdoの後に持っていったり、シェルスクリプトのパターンマッチを用いるなど)、極端な例として挙げておきます。
for file in `ls -1 datasets | xargs -I {} basename / | sed 's/*_\(.\).txt/\1.txt/g' | ....... `; do
このようなシェルスクリプトは書き終えた時は満足感にひたるのですが、後日メンテナンスや処理を書き換えようと思うと頭が痛いものです。
! Pythonでバッチ処理を書いてみる
その前に…
*シェルスクリプトの文法チェッカー([[ShellCheck|https://github.com/koalaman/shellcheck]])は入れていますか?
ここからは実際に自分が書いたシェルスクリプトをPythonで書き換えていきます。
Pythonは3.x系を想定しています。
!! subprocess
! Pythonでバッチ処理を書くことのデメリット
!! 2.X系、3.X系の互換性
! シェルスクリプト or Python のベストプラクティス
! まとめ