web-dev-qa-db-ja.com

パイプの代わりに誤って出力リダイレクトを使用した|

1か月前にPythonスクリプトを作成して、stdinからMACアドレスとIPアドレスをマップしました。2日前にそれを覚えており、tcpdumpの出力をフィルターするために使用しましたが、タイプミスの。私はタイプした

tcpdump -ne > ./mac_ip.py

出力は何もありません。しかし、入力を解析できない場合、出力は「不明」になるはずなので、cat ./mac_ip.pyとプログラムの代わりにすべてのtcpdumpデータを見つけました。その後、私は

tcpdump -ne | ./mac_ip.py

プログラムを元に戻す方法はありますか?とにかく私は自分のプログラムをもう一度書くことができますが、より重要なプログラムでそれが再び起こる場合、私は何かをすることができるはずです。 OR出力リダイレクトにファイルをチェックして実行可能ファイルかどうか警告する方法はありますか?

21
Bharath Teja

残念ながら、私はあなたがそれを書き直す必要があると思います。 (バックアップがある場合は、それを取得するときです。ない場合は、将来のためにバックアップ体制を設定することを強くお勧めします。多くのオプションが利用可能ですが、この回答についてはトピック外です。)

実行可能ファイルを別のディレクトリに置き、そのディレクトリをPATHに追加すると役立つことがわかりました。この方法では、明示的なパスで実行可能ファイルを参照する必要はありません。個人用(プライベート)スクリプトの優先プログラムディレクトリは"$HOME"/binで、PATH="$HOME/bin:$PATH"を使用してプログラム検索パスに追加できます。通常、これはシェルの起動スクリプト.bash_profile.bashrcに追加されます。

最後に、すべての実行可能プログラムに対する自分の書き込み権限の削除を止めるものは何もありません。

touch some_executable.py
chmod a+x,a-w some_executable.py    # chmod 555, if you prefer

ls -l some_executable.py
-r-xr-xr-x+ 1 roaima roaima 0 Jun 25 18:33 some_executable.py

echo "The hunting of the Snark" > ./some_executable.py
-bash: ./some_executable.py: Permission denied
22
roaima

リダイレクトによって既存のファイルが上書きされるのを防ぐには、>noclobberbashオプションを使用するか、機能が実際に発生した(t)cshのPOSIXのようなシェルを使用します。ただし、set noclobber/set -o noclobberの代わりにset -Cを使用します)。次に、ファイルを強制的に置き換える必要がある場合は、>|リダイレクト演算子(>!(t)csh)を使用します。

例:

$ echo abc > file
$ set -o noclobber
$ echo xyz > file
bash: file: cannot overwrite existing file
$ echo xyz >| file
$ cat file
xyz

ところで、現在の設定はset -oで確認できます。

$ set -o
...
monitor         on
noclobber       on
noexec          off
...
38
jimmij

重要なスクリプトgit repoの下でリモートで同期することを強くお勧めします(a 派手な自己ホスト型プラットフォーム はそうします)、@ caseyのコメントが言うように。

このようにして、ファイルを以前の作業状態に戻し、それを再度実行するなどの人的ミスから保護されます。

8
RcrdBrt

ファイルは回復可能ですか?

短い答え:通常はありません。

@Mark Plotnickがコメントで指摘している、あなたは回復できる.pyファイル.pycncompyle を使用します。これはあなたの状況にぴったりです。

ただし、一般に、これははるかに困難です。理論的には、フォレンジックツールを使用してファイルの削除を取り消すことができます。おそらく、私が使用した最も簡単な方法は testdisk (aka "PhotoRec")です。それは時々しか機能せず、遅いプロセスです。それは通常価値がないので、はい、それは可能ですが、本当の答えは「いいえ」です。

>は、実行可能ファイルを上書きしないように変更できますか?

いいえ。実行可能とマークされたファイルのみをリダイレクトしないようにシェルに指示する標準的な方法はありません。 「noclobber」があり、実行可能ファイルであるかどうかにかかわらず、既存のファイルへのリダイレクトを防止しますが、以下のコメントを参照してください。

将来どうする?

  1. これはばかげているように聞こえるかもしれませんが、将来の間違いを防ぐために、おそらく何もする必要はありません。私の賭けは、あなたがすでにこのレッスンを学んだということです。

    私は非常に長い間、Unixを使用および教育してきましたが、人々はこの間違いを一度は犯すことがよくありますが、それを繰り返すことはほとんどありません。何故なの?同じ理由で、ナイフで経験した人は自分を切り取らないでしょう:人間は学習が得意です。最終的に、正しいことをすることが第二の性質になります。

  2. バックアップを作成するテキストエディターを使用します。たとえば、 emacs を使用する場合、プログラムの以前のバージョンはmac_ip.py〜に保存されます。他のエディターも同様に機能するように構成できます(例:.nanorc)。自動バックアップをサポートしていないエディターの場合、.bashrcで単純な関数を作成できます。

    myeditor() { cp -p "$1" "$1~";  editor "$1"; }
    
  3. 自分で簡単にコピーを作成できるようにします。たとえば、作業中のプロジェクトのディレクトリに、次のようなターゲットを持つMakefileがあるとします。

    # Use `make tar` to backup all files in this directory.
    # Tar filename will be ../<currentdirectory>-<date>.tar.gz 
    DIRNAME = $(Shell basename `pwd`)
    TIMESTAMP = $(Shell date +%s)
    tar:
        @echo "[Tarring up ${DIRNAME}.tar.gz]"
        (cd .. ; tar -zcvf "${DIRNAME}-${TIMESTAMP}.tar.gz" "${DIRNAME}")
    

    (注:stackexchangeは、上記のTABを4つのスペースとして誤ってレンダリングしています。)

  4. 同様に、rsyncアクセス権を持つリモートUNIXホストに対してsshを実行するMakefileターゲットを作成できます。 (使用する ssh-copy-idそのため、パスワードの入力を繰り返し求められることはありません。)

  5. git を使用します。開始するには、多くの優れたチュートリアルがあります。お試しください man gittutorialman gittutorial-2 および man giteveryday 。独自のgitリポジトリをセットアップするのは難しくありませんが、github.comで無料でリモートリポジトリを作成することもできます。

  6. 上記のソリューションが重すぎる場合は、小さなスクリプトを Gist.github.com に保存できます。 Webブラウザーから貼り付けたりアップロードしたりすることは可能ですが、物事を非常に簡単にするために コマンドラインGistインターフェース を使用することをお勧めします。

「noclobber」を使用しないことを強くお勧めします。

はい、必要に応じて、set -o noclobberそのため、既存のファイルを上書きしようとすると、エラーメッセージが表示されます。これは私の考えでは悪い考えです。*

シェルが非標準的な方法で機能するようになり、シェルが有効になっているかどうかは表示されません。通常のことを行うには、別の構文を使用する必要があります。最悪の場合、noclobberに慣れたら、いつの日かnoclobberのない別のUnixマシンを使用して、この種の事故が再び発生する可能性があります。

ご存じのとおり、Unix Shellは専門家向けの鋭いツールとして設計されました。使い方は速く、邪魔になりません—どちらの端が先が尖っているか忘れてしまうと、それはあなたをカットします。でも、使えば使うほど、いいことになると思います。


* 脚注:おそらく私の意見を一粒の塩でとってください。私はまた、自転車の補助輪は悪い考えだと思う人です。

4
hackerb9

スクリプトを最近表示または編集していて、まだメモリバッファに残っている場合は、最初に発生した後にデータを回復できた可能性があります。そうでなければ、あなたはかなり運が悪いです。

>(またはtee -aではなく>>)ではなくteeにパイプしてファイル(およびSTDOUT)に書き込む場合、次にteeをエイリアス、関数、または書き込み先のファイルが実行可能である場合にユーザーに警告するスクリプトへのシンボリックリンクに簡単に置き換えることができます。

以下は決して理想的なものではなく、かなりで改善できる可能性がありますが、これは、これがどのように可能であるかの例としての出発点です:

wee.sh:

#!/bin/bash

if [ -n "${2}" ]; then
  if [ "$(ls -l "${2}" | awk '{print $1}' | grep x)" ]; then
    echo executable
  else
    tee -a "${2}"
  fi
Elif [ "$(ls -l "${1}" | awk '{print $1}' | grep x)" ]; then
  echo executable
else
  tee "${1}"
fi

...それからecho 'alias tee="/path/to/wee.sh"' >> ~/.bashrcまたは同様のもの。

明るい面では、少なくとも練習が増え、2番目のバージョンのPythonスクリプトはおそらく最初のスクリプトよりもはるかに優れています!

2
rubynorails

PCとサーバーのどちらで作業しているかは指定していません。ファイルが専用のファイルサーバーに格納されている場合、ファイルサーバーハードウェア(上のOS)によって保持される自動バックアップ( "スナップショット")がよくあります。

Linuxで

仮想非表示スナップショットディレクトリは、ファイルシステムのすべてのディレクトリに存在します。

試してください:

cd .snapshot   
ls -l

そのディレクトリが存在する場合は、運が良いかもしれません。特定の時点で自動的に保存されたバックアップを保持する一連のディレクトリが表示されます。名前は、スナップショットが保存された過去の相対時間を示します。例えば:

hourly.0
hourly.1
hourly.2
hourly.3
hourly.4
hourly.5
nightly.0
nightly.1
nightly.2
nightly.3
nightly.4
nightly.5
nightly.6
weekly.0
weekly.1
weekly.2

十分古い(ファイル上書きミスの前)の任意のタイムポイントディレクトリに移動します。タイムポイントディレクトリ内には、過去のその時点での../..ディレクトリ(およびすべてのサブディレクトリ)の状態が表示されます。

cd nightly.6
ls  # look around   
tee < mac_ip.py  # check for the correct content
cp mac_ip.py ~/safekeeping/mac_ip.py  # save the old file

ノート:

  1. ls -a.snapshotディレクトリを表示しません。明示的に名前を付ける必要があります。ファイルサーバーによって仮想的に挿入されます。ファイルシステムの実際のディレクトリとしては存在しません。
  2. これらの自動スナップショットはローリング履歴です。古い変更は最終的には失われ、失われます。ファイルを戻す必要があることに気付いたら、できるだけ早くこの手法を使用する必要があります。

Windowsで

非表示のスナップショットディレクトリは〜snapshotという名前で、特定のドライブのルートレベルにのみ存在します。

助言

スナップショットは、ほとんどの場合機能しますが、常に機能するわけではありません。ささいなファイルでもバージョン管理システム(gitなど)を使用するという他の推奨事項に同意します。

1
jskroch

それは以前に言われたことがあり、私はそれをもう一度言います。リビジョン管理システムを使用します。

バックアップは、ハードウェア障害を回復するためのものです。リビジョン管理はあなたのような状況のためのものです(他にも多くの用途があります)。リビジョン管理ツールを使用すると、ファイルの履歴を保持し、その履歴の任意の時点に戻ることができます。

リビジョン管理ツールの例としては、Subversion(SVN)(少し古くなっていますが、まだ使い勝手が良い)、Mercurial(hg)、git(git)(使いにくい)などがあります。 svnはオフィス文書に適しています。他のum-mergablesであるgitとhgは、他のほとんどの役割でそれを上回っています。 hgとgitを使用すると、配布とバックアップのために、オフラインで作業したり、リモートサーバーと同期したりできます。

リビジョン管理について読んでから、分散リビジョン管理を読んでから、それらを試してください。

1
ctrl-alt-delor