web-dev-qa-db-ja.com

コマンドラインの安全策

コマンドラインとスクリプトは危険です。 rm -rfで少しタイプミスをすると、あなたは傷ついた世界にいます。インポートスクリプトの実行中にデータベースの名前のステージとprodを混同すると、骨が折れます(同じサーバー上にある場合、これは良くありませんが、起こります)。 sshedするサーバー名が、いくつかのコマンドを実行した後のサーバー名ではないことを、遅すぎることに気付いても同じです。 Hole Hawg を尊重する必要があります。

私は危険なコマンドを実行する前にいくつかの小さな儀式を持っています-私がいるサーバーのトリプルテイクチェックをするようなものです。これが rm安全に関する興味深い記事 です。

コマンドラインで安全を保つための小さな儀式、ツール、トリックは何ですか?そして、「最初にls foo *を実行し、その出力を確認し、次にlsをrm -rfで置き換えてrm -rf foo *またはそのようなものを実行しないようにする」などの客観的なことを意味します。「コマンドでできます。」.

34
deadprogrammer

うまく機能するのは、シェルでプロダクション、ステージング、テストサーバーのさまざまな背景色を使用することです。

45
andyhky

開始する前に、バックアウト計画を念頭に置いてください。

  • ファイル/ディレクトリをすぐに削除するのではなく圧縮する
  • (Cisco)ルーターを「x」分以内に再起動するように設定し、すぐに「wr」しないでください
  • 変更するインターフェイスがシステムに入ったインターフェイスではないことを確認してください。これは、Telnet接続したルーターインターフェイスか、VNC接続したイーサネットポートです。
  • 「ルート」としてログインしないでください
  • バックアップを作成します。それが良いことを確認してください。別のものを作ります。
  • 信頼できる人に尋ねてください。
14
Peter

これはWindows Powershellに固有のものです。

ポリシーとして、次のマシンprofile.ps1を各サーバーに追加します。これにより、次のことが確実になります。

  1. 管理PowerShellコンソールウィンドウの背景色は濃い赤
  2. タイトルに管理者が追加されました
  3. 「警告:管理者としてPowershellが実行されています。」というメッセージ起動時に書き込まれます
  4. タイトルバーの先頭には「Administrator:」が付いています
  5. パスには、標準のユーティリティ(企業のシェルスクリプト、vim、infozipなど)が含まれています。
 $ currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity] :: GetCurrent())
&{
 if($ currentPrincipal.IsInRole([ Security.Principal.WindowsBuiltInRole] :: Administrator))
 {
(get-Host).UI.RawUI.Backgroundcolor = "DarkRed" 
 clear-Host 
 write-Host "警告:PowerShellは管理者として実行されています。`n" 
} 
 
 $ utilities = $ null 
 if([IntPtr] :: size * 8 -eq 64)
 {
 $ Host.UI.RawUI.WindowTitle = "Windows PowerShell(x64)" 
 $ utilities = "$ {env:programfiles(x86) }\Utilities "
} 
 else 
 {
 $ Host.UI.RawUI.WindowTitle =" Windows PowerShell(x86) "
 $ utilities = "$ {env:programfiles}\Utilities" 
} 
 if((Test-Path $ utilities)-and!($ env:path -match $ utilities.Replace( "\"、 "\\")))
 {
 $ env:path = "$ utilities; $ {env:path} "
} 
} 
 
関数プロンプト
 {
 if($ currentPrincipal.IsInRole([Security .Principal.WindowsBuiltInRole] :: Administrator))
 {
 if(!$ Host.UI.RawUI.WindowTitle.StartsWith( "Administrator:"))
 {$ Host。 UI.RawUI.WindowTitle = "Administrator:" + $ Host.UI.RawUI.WindowTitle} 
} 
 'PS' + $(if($ nestedpromptlevel -ge 1){'>>' })+ '>' 
} 
10
Brian Reiter

これらのいくつかに対するローテクソリューションがあります。

私は次のことをする癖をつけてきました(rootとして働くことを計画しているとき):

  • まず、通常のユーザーとしてログインし、次にSudo su - rootを使用してrootに切り替えます。私はこれを精神的な準備として、非常に危険なエリアに精神的に入り込んだことと、常に警戒し、常に警戒している必要があることを思い出させるために行っています。おかしなことに、この小さな儀式だけで、それを補強するだけで、多くの悲しみを救うことができます(= /// =)私は不注意ではありません
  • 各コマンドは入力されますが、[Return]キーは押されません決して
  • コマンドはありませんever理解せずに実行されます正確にコマンドの動作何をしているのか知らずにこれを行っている場合は、システムで ロシアンルーレット をプレイしています。
  • [Return]キーを押す前に、CLIで強制終了されたコマンドが目で注意深く検査されます。ためらいや潜在的な問題のヒントがある場合は、再度検討されます。そのためらいが続く場合は、コマンドをそのままにして、F2キーを押しながら別のコンソールに移動して、manページなどを調べます。グラフィカルセッションの場合は、ブラウザーを起動して検索を行います。
  • 私のシステムでは、一般的なユーザーにSudoが渡されません。not私はBOFHです ですが、準備とトレーニングがないため、これは、ロードされた銃をサルに与えるようなものです。猿が樽を見下ろして圧迫するまでは、最初はおもしろくて楽しいです...

Rmを使用するときは、常に最初にディレクトリにcdし、次にプレフィックス./を使用して、ディレクトリが正しいことを確認します。

cd /usr/some/directory ; rm ./targetfile

または、ファイルの完全なパスを指定します

rm /usr/some/directory/targetfile

これはPITAですが...申し訳ありませんが安全です。

10
Avery Payne

上記のすべての答えに同意できますが、これは非常に重要なヒントです。

マルチタスクを回避するタイミングを知る。

6
ojblass

サーバーを変更する前に知っておくべき重要なことはほとんどありません。

  • 適切なサーバーにいることを確認してください

  • **このアクションの影響を受ける人数*(間違いを犯したかどうかに注意)

  • Enterキーを入力する前に、元に戻す可能性に注意してください

  • このコマンドがセッションを切断する可能性があるかどうかを自問してください(fwルール、不適切なシャットダウンなど)。フェイルオーバーが発生することを確認します(特にオフサイトの場合)。

5
l0c0b0x

私がいるシステムのホスト名がbash(または他のシェル)プロンプトにあることを確認します。私がchrootされた場合、私はそれが何らかの形でそこにも入ることを確認します。

私はかつて別のライブLinuxディストリビューション内からGentooシステムをインストールしていて、誤ってかなり破壊的なコマンド(ATMを思い出せない-rmのバリアント)を間違ったシェルで実行したため、大量のものが発生しましたchroot内からのものではなく、削除するライブシステム上。それ以来、私はいつもしました

export PS1="(chroot) $PS1"

chroot内で作業しているときはいつでも。

5
Tim

ルール1-バックアップを作成する

ルール2-[〜#〜] never [〜#〜]「molly guard」ラッパーを標準コマンドに追加し、独自のバージョンを作成しますが、名前を引き継がないでください。セットアップしていないシステムを使用しているときは、噛んでください。

ルートと(部分的な)ディレクトリツリーの色の違いなどのプロンプトトリックは優れたヘルパーですが、繰り返しになりますが、それらがなくても作業できます。

4
LapTop006

まだ行っていない場合は、rmをrm -iにエイリアスします。

4
trent

これは直観に反し、あまり「わかりにくい」ように見えるかもしれませんが、私が持っているコマンドラインの安全性に関する最高のヒントは次のとおりです。GUIモードの代替が利用可能で実用的である場合、USE IT.

どうして?とてもシンプルです。 GUIモードには通常、「警告-フリーフローフロッグをくすぐろうとしています。これを実行してもよろしいですか?」という形式のセーフティネットが組み込まれています。そうでない場合でも、それはあなたを遅くし、思考時間のためのより多くの余地を与えます。コミットする前にオプションを簡単に再確認でき、状態の前後のスクリーンショットを撮ることができ、タイプミスから保護します。すべての良い、便利で役立つもの。

恐ろしい「rm -rf」の古典的なケースでは、GUIまたはCLIから誤って発行する方が簡単だと思いますか?

結局、GUIを使用することに恥はありません。大災害を確実に防ぐことはできません。 CLIの場合と同じように、GUIの場合もトリガーハッピーになることができます。しかし、それ自体が価値があると証明されたら、それがあなたを救うなら。

4
Maximus Minimus

Rmをrm -iにエイリアスする代わりに、removeまたはsaferemoveとエイリアスするほうがよいでしょう(そして、それらを優先する削除ツールとして使用します)。次に、これが設定されていないボックスを使用しても、損傷はありません。

3
DBMarcos99

常識を使用し、理解できないコマンドを実行しないでください。それはすべて良いアドバイスです。 rmに渡すすべての絶対パスを書き出す、またはSudo経由で何かを実行するのに苦労したい場合は、自由に感じてください。私はそのときsu -cを好みます。少なくともパスワードはキャッシュしません。通常のユーザーがパスワードの確認なしにroot権限で物事を実行することを許可されていることに私は気が進まないでしょう。

〜/ .bashrcに安全性を高めるために、次のようないくつかの点を追加できます。

alias srm='rm -i'

Rmの安全な代替手段を使用できるようにする...

しかし、結局のところ、失敗する可能性があり、常に失敗します。先日、機能しないconfigureスクリプトを使用して/ usr/binフォルダー全体を削除し、いくつかの問題を解決しました。はい、バグのあるあらゆる種類のソフトウェアを単純に「インストール」すると、システムが壊れる可能性があります。あなたが何をしても、あなたは決して安全ではありません。私が得ているのは、最も重要なことです:

定期的なバックアップを保持します。

3
jns

Bashを使用する場合は、次のことを試してください。

TMOUT=600

あなたの/root/.bashrc または類似。それは10分後に自動的にログアウトし、誤って開いたままにしておかしなものを入力したルートターミナルにフリップする可能性を減らします。

はい、私はあなたがルートコマンドを実行するためにあなたがSudoを使うべきであることを知っています-これはあなたがある日それを危険にさらすことに決めた場合に備えた単なる追加の安全策です。

2
Andrew Ferrier

彼らが何をしているかを完全に理解していない限り、あなたがオンラインで見つけたコマンドを決して実行しないことを確認してください。

あなたのシステムは投稿者のシステムとは異なる場合があり、それが世界を傷つける可能性があります。

2
jjnguy

Unix/Linuxの観点から見たコマンドラインの安全性の明らかなものは、rootアカウントの適切な使用です。
ルートとしてのrm -rfは一般にユーザーとしてよりも危険であり、ルートとしてログインするのではなく、Sudoなどの組み込みのものを使用することが重要です。素敵な単純なwhoamiは、通常、統合失調症や複数の人格に役立ちます。

特にglobまたはregexが正しく一致していることを確認したい場合は特に、ファイル変更コマンドにエコーを付加します。

2
Andy
# Allow only UPDATE and DELETE statements that specify key values
alias mysql="mysql --safe-updates"`

Mysql CLIを使用する場合に備えておくことを強くお勧めします。

2
jldugger

作業中のマシンに2次接続があると、1次セッションを終了したり、ばかげた何かをしてロックアップしたり、重い処理をしたりする場合に便利です。

そうすれば、マシンに引き続きアクセスでき、プライマリセッションを強制終了できます。

上記のコメントのほとんどはrmを参照していますが、他のコマンドでもいくつかの愚かなことをしています...

ifconfigがネットワークを停止する-さて、修正するには物理的な存在が必要です。

スクリプトに関しては、私は通常2つのウィンドウで作業します。 1つ目はスクリプトの記述に使用し、2つ目は記述しながら各行をテストします。ゆっくりと注意深く進むことで、コードを書くときにすべての行が期待どおりに機能することを確認できます。同じ変数を維持するように注意します。

個人的には、rm -iなどの追加のプロンプトは本当に役立ちません。 v。疲れている、ストレスが多いなどの場合、ほとんどの間違いを犯します。それは、とにかくプロンプトを無視しているだけのときです。たぶん悪い習慣。

2
Alex

オペレーティングシステムの複数のバリアントを使用する場合は、very構文の違いに注意してください。あるUNIXバリアントで合理的に安全なものは、別のものでは非常に危険です。

例:killall

Linux/FreeBSD/OSX-渡されたパラメーターに一致するすべてのプロセスを強制終了します。例:「killall Apache」はすべてのパッチを終了し、他のすべてのプロセスはそのままにします。

Solaris-allプロセスを終了します。いや、本当に。 man page から:shutdown(1M)はkillallを使用して、シャットダウン手順に直接関連しないアクティブなプロセスをすべて強制終了します。

1
Greg Work

Lsの代わりにechoを使用して、シェルがすべてを展開した後に完全なコマンドを表示できるようにします。また、常にファイルを表す変数を二重引用符で囲んで、タブやスペースが含まれている可能性のあるファイル名を操作できるようにします。

1
Kyle Brandt

あなたがやっていることを考えさせる素晴らしい方法は、ルートのbashrc(cshrcなど)に次のようなものを追加することです。

unset PATH

そうすれば、 "rm"だけでなく、/ bin/rmを実行する必要があります。それらの余分な文字は、あなたに思わせるかもしれません。

1
Bill Weiss

他のいくつかの投稿の少しメタ:最初に提案されている通常のecho/ls手順を使用して、コマンドが必要なファイルのセットを選択していること、または意図したとおりにシェルによって解釈されていることを確認します。

しかし、その後、前のコマンドを取得するために、シェルのコマンド履歴編集機能を使用しますmodify変更する必要がある部分のみ。

これらの各コマンドを個別に入力してもまったく役に立ちません...

$ ls *.bak
$ echo rm *.bak
$ rm * .bak

...誤って最後の行にスペースを入力して、すべてのファイルを削除したためです。私は常に前の行を取得し、単に「エコー」を削除します。

1
Zac Thompson

複雑な正規表現の場合、特に「検索」コマンドはエコーを前に置き、それらをファイルにキャプチャします。次に、「ソース」でファイルを実行する前に、あなたが本当に思っているとおりに本当に削除/移動/などしていることを確認できます。

また、正規表現で検出されなかったEdgeケースを手動で追加する場合にも便利です。

1
Martin Beckett

rootユーザー:
必要がない限り、rootにならないでください。
ベンダーがrootとして実行する必要があると述べた場合は、自分が顧客であり、非rootとして実行することを伝えます。
「簡単だからといって」既成のソフトウェアパッケージのうちどれだけがrootを必要としていますか?

習慣:
決して「*」を削除なしで3回見ないで使用しないでくださいls -l TargetPatternを使用する習慣を付けてから、「rm!$」を使用することをお勧めします。最大の脅威は、自分がいると思っているところにいないことです。 I ほぼ 'ls'と同じくらい頻繁に 'hostname'を入力します!

松葉杖:
「alias rm = 'rm -i'」のようなエイリアスがそうであるように、標準のプロンプトは多くのことを助けますが、私はしばしば私が使用しているマシンを完全に制御できないため、expect '-i'でパス、プロンプト、エイリアスを設定するだけのラッパースクリプト

問題を見つける:
フルパスを使用すると役立ちますが、それが不可能な場合は、より安全な場所にcdし、「&&」を使用して、検索、削除、tar、 untarなど:
例:cd /filesystema && tar cf - | ( cd /filesystemb && tar vxf -)
「&&」を使用すると、この場合、tarファイルがそれ自体の上に抽出されるのを防ぐことができます(ただし、この場合は「rsync」の方が適しています)。

削除:
特にスクリプトで、それが役立つ場合は再帰的に削除しないでください。 -type fと-name 'pattern'を使用して検索および削除します。xargsに 'nothing'を供給するのがまだ怖いです。

1
ericslaw

* globを可能な限り独自の引数として使用します。私が本当に「このディレクトリのすべてを削除する」ことを意味する場合でも、私はより具体的にするように努めます。 rm *.php。別のディレクトリの履歴から誤って同じコマンドを実行した場合に備えて、これは予防的な損傷制御です。

1

次のような場合:

ls * .php
エコーrm * .php
rm * .php

次のように、置換演算子を使用できます。
$ ls * .php
<ディレクトリリスト>

$ ^ ls ^ echo rm(これにより、前のコマンドのlsがecho rmに置き換えられ、残りのコマンドラインは同じままになります)

$ ^ echo rm ^ rm(echo rmをrmだけに置き換えます。したがって、*。phpを再入力してスペースを誤って入力する必要はありません)

^ = shift-6、慣れていない人のために。

0
Red Five

最初にエコーを指定してコマンドを実行することをお勧めしますが、それでもタイプミスが発生しやすくなります。

!$などの展開で使用してみてください。

echo foo*
rm -rf !$

!$は最後のコマンドの最後のWordに展開されるため、以下と同等です。

echo foo*
rm -rf foo*

最後のコマンドのすべての引数に展開される!*もあります。

確かに、あなたが望むなら、あなたはこのようにそれを行うことができます

echo rm -rf foo*
!*

(bashではなくkshを使用している場合は、代わりにEsc + periodを入力して最後のWordを挿入できます。)

0
Mikel

の代わりに

rm foo*

使用する

rm -i foo*

これは少数のファイルでは実用的ですが、たとえばtarball全体ではそうではありません。これが、エイリアスrmが邪魔になる理由です。

0
gbarry

Bashを使用してPS1 = '\ u @\h:\ w>'を設定します。これは、username @ hostname:/ full/working/directory/path>に展開されます。他の回答で述べたように、.profileまたは.bash_profileファイルを更新できない場合は、ログインするたびに環境の設定を期待して使用できます。ただし、背景色を変更するのが最善の答えです:-)

0
dr-jan