Bashで`rm -rf *`コマンドが実行される前に警告するプロンプトを実装する

    >

プログラミングは、進む時は面白いぐらいに進むのに、詰まる時はとことん詰まる。そしてそのままフェードアウト…といったことはよく聞く話です。僕もHTMLから始めて、長いことプログラミングを続けてきましたが、どうしても自分の思い通りにいかない、実装ができない、エラーが続く、といった状況に悩まされ、うつ状態になり、もういっそプログラミングなんて辞めてしまおうか…と挫折しそうになった経験が、幾度となくあります。

プログラミングを6年続けてきて、プログラミングは自分一人で完結できるものではない、ということは痛いほど分かっています。"スタックオーバーフロー"だけではどうしようもないことも、中にはあります。 特に、新しい技術や言語に挑戦しようとする時は、難関が数多くあります。JavaとPHPは違いますし、スマホアプリが作れるからと言ってPythonができるとは限りません。多くの場合、多くの障壁に立ち塞がることでしょう。

実際、僕も多くのプログラミングをしている友人から、あらゆる相談を受けます。既存の回答や僕の知識から、最適な答えを返してあげられることもありますが、答えられないことや上手く説明できないことも多くあります。
そのような場合、僕が彼らに勧めているのが、『TechAcademy [テックアカデミー]』です。

同サービスは短期間から登録できるオンライン完結のプログラミングスクールで、他社と比較しても、そのコストパフォマンスは圧倒的です。
例えば、A社は148,000円〜のところ、同サービスは99,000円〜でコースが受講できます。( ※はじめてのプログラミングコース4週間の料金 )
また、一言に現役のプロと言っても、エンジニア歴20年以上、プログラム歴35年以上といった、まさにプロ中のプロの方たちが対応してくれるのも、『techacademy』の魅力の一つ。

国内外どこからでもチャット相談が可能で、毎日8時間、1週間あたり57時間の間、メンターが常時待機しています。
受講生限定の転職サポートで、コース受講終了後、企業やコンサルタントからスカウトが届く"TechAcademyキャリア"も、ぜひ活用したいところです。

  • オリジナルアプリをAppStoreにリリースするまで徹底サポート「iPhoneアプリコース」
  • 職業を問わず身につけたい、教養としてのプログラミングが学べる「はじめてのプログラミングコース」
  • 仮想通貨を支えるブロックチェーン技術の仕組みを学べる「ブロックチェーンコース」
  • Pythonと機械学習が学べる「Pythonコース」

『techacademy』では、上記コースをはじめとした、数多くの特化したコースが受講受付中です。プログラミングの進捗に真剣に悩んでいる方は、ぜひご活用ください。

TechAcademy [テックアカデミー]

さて、おまたせしました。

今回の記事は『Bashで`rm -rf *`コマンドが実行される前に警告するプロンプトを実装する』です。この記事が役に立った、と思ったらぜひ、コメントまたはTwitterやLINEでシェアしてくださいね。


どうも。先日.bashrcが10000行を超えたのを皮切りに今更zshに乗り換えようか検討しています。yuisです。

Linuxコマンドrm -rfは最も危険なコマンドのひとつとして名高いですね。近年ではサーバー管理者が意図せずこのコマンドを実行してしまい全データを消してしまったという話も聞いたことがあります。
かく言う僕も、このコマンドにまつわるこんな経験があります。

それは、ある友人にMacOSXのレクチャーをしてあげていたときに起こりました。その友人はクソ不真面目な野郎で、それを承知の上で僕は、パソコンに疎いというその友人にメールのやり方やら色々と教えてあげていました。そしてある時、友人はお得意の「もうやだ。やめたい。才能がない」などと喚き散らし、それを発端としていつの間にやら、僕らはいつもの喧嘩をはじめていました。ほどなくして我慢の限界を超えた僕は、ついに例のコマンド、rm -rfを実行し、そしてそのMacは二度と起動することができなくなってしまいましたとさ。

※ このMacパソコンは契約のもの僕がプレゼントしてあげたものです。違法性はありませんのでご安心ください。

今回はそんなrm -rfコマンドの危険性を少しでも下げることができたらという思いつきから書いたコードを紹介します。


僕もそうですが、フリーのプログラマの仕事内容は様々です。ソフトウェアを受注製作することもあれば、企業ホームページを作ることもあるでしょう。
どういったビジネスを展開するにせよ、事業を成功させるには、正しいマーケティングを行うことは必須事項です。

ミツモア』は、Googleのリスティング広告やマーケティング広告管理に煩わされることなく、狙った顧客を獲得できる、マーケティングプラットフォームです。
僕のプログラマの友人がいるのですが、彼にも『ミツモア』を紹介し、彼は現在、成功したプログラマの一人です。
どうしても疎かになってしまいがちなマーケティングですが、『ミツモア』を上手く活用し、新たな新規顧客を獲得していきたいところですね。

ミツモア

使用例

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_2675b7f6-aeb0-4f5b-a77e-31850e7064d8.gif

$ tmpdird # 新規ディレクトリへ移動

$ ls
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .

$ genfiles 3 # ファイルを生成

$ ls
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
  8444249304069546 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 3.txt
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .
 51509920740553578 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 2.txt
 36310271996515302 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 1.txt

$ rm -rf * # 全ファイルを削除 > 確認プロンプト > n
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
n

$ ls # ファイルが消されていないことを確認
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
  8444249304069546 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 3.txt
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .
 51509920740553578 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 2.txt
 36310271996515302 -rwxrwxrwx 1 yuis yuis    2 Jul 10 21:59 1.txt

$ rm -rf * # 全ファイルを削除 > 確認プロンプト > y
W: It seems You are attempting to run kind of dangerous command. Continue? [y/n]
y

$ ls # ファイルが消されてることを確認
total 0
166351711236005864 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 ..
 23080948093026057 drwxrwxrwx 1 yuis yuis 4096 Jul 10 21:59 .

上記のような具合に、rm -rf *を実行しようとすると、実行される前に警告を行うプロンプトをします。yで実行をし、nで実行をキャンセルします。

コード


ok(){ : <<< ' yes or no prompt e.g. printf "The file alredy exist here. Override it? " ; ok && echo y || echo n ' read -n 1 -r ; [[ $REPLY =~ ^[Yy]$ ]] && { echo ; return 0 ; } || { echo ; return 1 ; } } red=$'\e[1;31m' grn=$'\e[1;32m' yel=$'\e[1;33m' blu=$'\e[1;34m' mag=$'\e[1;35m' cyn=$'\e[1;36m' end=$'\e[0m' warn(){ printf "${yel}W: ${*}\n${end}" >&2 } ## shopt -s extdebug preexec_invoke_exec () { [ -n "$COMP_LINE" ] && return # do nothing if completing [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`; # So that you don't get locked accidentally if [ "shopt -u extdebug" == "$this_command" ]; then return 0 fi # // filtering # Modify $this_command and then execute it # eval "${this_command}" # echo "${this_command}" if [[ "${this_command}" =~ ^(somethingdangercommand$|somethingdangercommand[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return elif [[ "${this_command}" =~ ^(anotherSomethingdangercommand$|anotherSomethingdangercommand[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return elif [[ "${this_command}" =~ ^(rm[[:space:]][-rf]{3}$|rm[[:space:]][-rf]{3}[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return else eval "${this_command}" fi # // filtering return 1 # This prevent executing of original command } trap 'preexec_invoke_exec' DEBUG

上記コードを${HOME}/.bashrcへ追記し、試しに未定義のコマンド、somethingdangercommandコマンドを実行してみてください。未定義のコマンドなので通常だったら未定義ですよというエラーが出るところですが、プロンプトでnをエンターすることでコマンド自体が実行されないので、エラーが出ずに終了します。

trap 'preexec_invoke_exec' DEBUG … 毎コマンド実行前にpreexec_invoke_exec()を実行

elif [[ "${this_command}" =~ ^(rm[[:space:]][-rf]{3}$|rm[[:space:]][-rf]{3}[[:space:]]) ]]; then warn "It seems You are attempting to run kind of dangerous command. Continue? [y/n]" ; ok && eval "${this_command}" || return … 実行されたコマンドがrm -rfrm -frのとき警告をする

コマンドを実行する前にコマンドが正規表現に一致するかなど、フィルタをし、フィルタにかかった場合に警告をし、それ以外の場合には通常通り渡されたコマンドをevalしている感じですね。

参考

Linux trap command help and examples
linux – Modify all bash commands through a program before executing them – Unix & Linux Stack Exchange

結論

https://yuis.xsrv.jp/data/MjQuC3Aeoxgi4YZvwYxCRCXfuwXbGI1H.png

rm -rfの事故はエクスクラメーション展開で起こってしまうことが多いようです。使わない場合は無効化しておくといいですね。

# disable/turn off history expansion `!` altogether
set +H

2020年の東京五輪を間近に控え、来日外国人の数は年々増加しています。ただでさえ、あらゆる職種で"英語力"が求められる時代ですが、その中でも特筆してプログラマ、システムエンジニアには、英語力は必須であると言われています。

僕は現在、英検1級に着手し、英語力が一定水準に達した今でも、日々新しい表現や単語を学んでいます。しかし僕も最初から英語が出来たわけではありません。中学生の頃の英語の成績は、学年でほぼビリでしたし、そもそも英語なんて必要ない(若者の常套句ですね)、今後一生やることはない、と思っていたくらいです。

確かに、英語を使わずとも年収600万以上の仕事に就くことは出来ますし、生活する上で困ることもないでしょう。しかしそれは、英語を知っている世界を知らないからでしかありません。
英語に興味関心がない多くの方は、こういうことを言うと反発するのですが、プログラミング経験者の皆さんなら、そうでもないのではないでしょうか。

プログラミングをやっていて、英語が出来たらなぁと思ったこと、あるのではないでしょうか。僕が英語を始めた動機は他にありますが、一度、二度挫折した英語学習を再開する動機となったのは、紛れもなく、"プログラミング"でした。プログラミングを続けるには、英語の壁を超える必要がある、と幾度となく痛感しました。

  • エラー文章をGoogle検索せずとも理解できる
  • ソースコードに日本語が含まれる場合に起こる特有のエラーを回避できる
  • スタックオーバーフローの回答が理解できる
  • スタックオーバーフローに質問を投稿し、良質で的を射た回答を得ることができる
  • 翻訳されていないドキュメントやリファレンスを理解できる
  • 適切なメソッド名やファイル名をスムーズに定義できる
  • 需要が高く報酬の良い海外で仕事が探せる、または海外のクライアントを相手にできる

上記をはじめとした、プログラミングにおいて英語ができることのメリットは数多く存在します。
英語学習の必要性に疑問を持っていた方も、上記の一覧を見て、何か思うことがあるかもしれません。しかし、英語を学習する意義を見つけたあと、間違っていけないのが、その学習方法です。

英語学習方法には効率的、非効率的、意味がないなど、様々な方法が乱立しています。中には悪徳なものもあり、注意が必要です。
英語学習に回り道やチートはありませんが、効率的でない学習方法を避けて学習を進めていくことは、1年後、5年後の自分の英語力に取り返しのつかない差が開いてしまうことを未然に防ぎます。

そして、僕が一番信頼を置いているのが、『スタディサプリ ENGLISH』です。『スタディサプリ ENGLISH』はこれまで様々な英語に関する相談をしてきた友人への、最も勧める頻度の高かったサービスです。

留学が間近で…、ワーキングホリデーに行ってみたくて…、やっぱり英語をまた始めようと思って…、社内公用語対策で…、英会話教室に通おうと思ってて…などなど、僕への相談は様々ですが、これら全ての方に、『スタディサプリ ENGLISH』は自信を持っておすすめできます。

スタディサプリ ENGLISH

さて、最後までお読み頂きありがとうございました。この記事が役に立った、と思ったらぜひ、コメントまたはTwitterやLINEでシェアしてくださいね。

僕は個人事業として、プログラミング6年、1日14時間パソコン業務をこなしてきました。現在もウェブサイト開発やサポート、ソフトウェア制作、レビューなどライティングをはじめとしたお仕事を承っております。気になったらぜひ、メールにてご連絡ください。いつでもお待ちしております。

現在承っているお仕事の一覧
お問い合わせ

小山はるや(こやまはるや) 東京生まれ。プログラマー。現役大学生。ウェブサイト制作の傍らメディア運営を行い、2017年に開設されたITブログ『yuipro』(https://yuis-programming.com)は2019年に月間アクセス数1万を超える。 これまで80を超えるウェブサイトを制作、小山氏自ら運営するウェブサイトは8つに上り、うち2つが月当たり数万のアクティブビジターを獲得している。


Close Menu