Случайно использовал перенаправление вывода> вместо канала |


21

Месяц назад я написал скрипт Python для сопоставления MAC-адресов и IP-адресов со стандартного ввода. И два дня назад я запомнил это и использовал для фильтрации выходных данных, tcpdumpно это пошло не так из-за опечатки. Я набрал

tcpdump -ne > ./mac_ip.py

и на выходе ничего нет. Но вывод должен быть «Неизвестен», если он не может проанализировать ввод, поэтому я сделал cat ./mac_ip.pyи нашел все tcpdumpданные вместо программы. Тогда я понял, что я должен использовать

tcpdump -ne | ./mac_ip.py

Есть ли способ вернуть мою программу? В любом случае я снова могу написать свою программу, но если это случится снова с более важной программой, я смогу что-то сделать. ИЛИ есть ли способ сообщить перенаправлению вывода, чтобы проверить файл и предупредить, если это исполняемый файл?


18
Вы можете вернуть свою программу из последней резервной копии перед перезаписью, иначе нет. Кстати, в оболочке вы можете указать, set -o noglobberи bash больше не будет перенаправлять в существующие файлы. Подробности смотрите здесь: cyberciti.biz/tips/howto-keep-file-safe-from-overwriting.html
eckes

12
У вас не должно быть разрешения на запись в важные исполняемые файлы ...
Хаген фон

20
@eckesset -o noclobber
GnP

38
@HagenvonEitzen Я ненавижу такой совет, как если бы вы установили правильное владение и права доступа для каждого одноразового shell-скрипта и скрипта Python, которые вы когда-либо писали перед его запуском (и, конечно, еще раз ненадолго, если вам нужно отредактировать его). ). Это лишь немного более значимо, чем «Вы не должны печатать, >когда имеете в виду |». Не забывай реальность.
Джейсон С

30
Git репо дешевы. Зафиксируйте весь свой код, независимо от того, насколько он мал и бессмыслен, а затем такая ошибка - это быстрое и простое исправление.
Кейси

Ответы:


22

К сожалению, я подозреваю, что вам нужно будет переписать это. (Если у вас есть резервные копии, самое время их извлечь. Если нет, я настоятельно рекомендую вам настроить режим резервного копирования на будущее. Множество доступных вариантов, но не по теме для этого ответа.)

Я считаю, что размещение исполняемых файлов в отдельном каталоге и добавление этого каталога в каталог 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

2
/usr/local/binявляется стандартным местом для пользовательских исполняемых файлов и скриптов
gardenhead

4
@gardenhead Это зависит от того, как настроена система. /usr/localпредназначен для специфичных для хоста вещей (в отличие от каталога, совместно используемого хостами через сетевое монтирование), и может быть или не быть доступным для записи пользователям без полномочий root.
chepner

4
@gardenhead, это одно стандартное место, конечно. Я использую /use/local/binдля локально установленных сценариев и программ, которые могут использоваться несколькими учетными записями, а также $HOME/binдля личных вещей одного пользователя. В обоих есть ценность.
Ройма

1
Обратите внимание, что Fedora, похоже, пытается использовать$HOME/.local/bin
Zan Lynx

1
@ Zan eeeww! Если серьезно, спасибо. Похоже, что RH пытается протолкнуть все, так ~/.localкак это еще один элемент, перемещенный из своего «традиционного» места.
Ройма

38

Чтобы предотвратить перезапись существующих файлов путем перенаправления, >используйте noclobberпараметр в bashлюбой POSIX-подобной оболочке (также в том месте, (t)cshгде эта функция фактически возникла, хотя вы делаете это set noclobberвместо set -o noclobber/ set -Cтам). Затем, если вам нужно принудительно заменить файл, используйте >|оператор перенаправления ( >!in (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
...

Хотя это отлично отвечает на вопрос, я бы не рекомендовал это. 1. Печатание >|вместо того, чтобы |не намного менее вероятно чем печатание >. 2. Создать резервные копии легко и настоятельно рекомендуется (редактор, достойный своего имени, может сохранить последнюю версию; есть и cronт. Д.). 3. Каждый кусочек кода должен быть поставлен под контроль версий, даже крошечные скрипты. YMMV.
Maaartinus

2
@maaartinus давай, 1) ввод двух отдельных символов вместо одного явно менее вероятен. 2) Очевидно, что резервные копии необходимы, никто не советовал ОП не делать резервных копий, этот ответ никоим образом не предполагает отсутствие резервных копий, и резервные копии редактора предполагают, что вы редактировали файл в редакторе. 3) Опять же, вы думаете только о коде, который написал OP, как в этом конкретном примере, но вопрос и этот ответ применимы к любому файлу на машине, включая системные исполняемые файлы.
Тердон

8

Настоятельно советую иметь важные скрипты под git-репо синхронизировались удаленно ( подойдет платформа с собственным хостингом ), как говорится в комментарии @ casey.

Таким образом, вы защищены от ошибок человека, таких как возврат файла в предыдущее рабочее состояние и выполнение его снова.


4

Можно ли восстановить файл?

Краткий ответ: обычно нет.

@Mark Plotnick указывает в комментариях, вы можете восстановить .pyфайлы с .pycпомощью Uncompyle . Это должно быть идеально подходит для вашей ситуации.

Но в целом все гораздо сложнее. Теоретически вы можете использовать криминалистические инструменты для восстановления файлов. Наверное, самое простое, что я использовал testdisk(так называемый «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 неверно отображает вкладки выше как 4 пробела.)

  4. Точно так же вы можете создать цель Makefile, которая обращается rsyncк удаленному хосту Unix, к которому у вас есть sshдоступ. (Используйте, ssh-copy-idчтобы вам не нужно было повторно запрашивать пароль.)

  5. Использование git. Есть много отличных учебников по началу работы. Попробуй man gittutorial, man gittutorial-2и man giteveryday. Настроить свой собственный git-репозиторий несложно, но вы также можете бесплатно создать удаленный репозиторий на github.com.

  6. Если приведенные выше решения имеют слишком большой вес, вы можете сохранить небольшие сценарии на gist.github.com . Хотя можно вставлять или загружать из веб-браузера, я рекомендую использовать интерфейс командной строки, чтобы упростить задачу.

Я настоятельно не рекомендую использовать "Noclobber".

Да, если вы выберете, вы можете сделать set -o noclobberтак, что вы будете получать сообщения об ошибках всякий раз, когда вы пытаетесь перезаписать существующий файл. На мой взгляд, это плохая идея. *

Это заставляет оболочку работать нестандартным способом без видимого указания, включена ли она. Вы должны использовать другой синтаксис для выполнения обычных вещей. Хуже всего то, что если вы привыкнете к noclobber, то когда-нибудь вы будете использовать другую Unix-машину без noclobber, и такого рода аварии могут произойти снова.

Как вы, наверное, знаете, оболочка Unix была разработана для того, чтобы стать хорошим инструментом для экспертов. Он быстрый в использовании и не будет мешать вам - и он порежет вас, если вы забудете, какой конец острый. Но чем больше вы его используете, тем больше я думаю, вы по достоинству оцените это.


* Сноска: возможно, примите мое мнение с недоверием. Я также человек, который считает велосипедные тренировочные колеса плохой идеей.


Я также некоторое время учил Unix. Многие из моих учеников никогда не учились ценить прямую простоту Unix; Я говорю им, что они не одиноки, и, по крайней мере, все еще могут учиться, сочувствуя «Справочнику ненавистника Unix», который наметил для них некоторые минные поля. simson.net/ref/ugh.pdf
Джейсон

Также: я согласен - тренировочные колеса на велосипеде полезны для всех, кто учится ездить на трехколесном велосипеде.
Джейсон

2

Возможно, вы смогли восстановить данные после того, как они впервые появились, если вы недавно просматривали или редактировали скрипт, и он все еще находился в буфере памяти. В противном случае вам не повезло.

Если вы отправили трубку для teeзаписи в файл (а также STDOUT) вместо >(или tee -aвместо >>), то вы могли бы легко заменить 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или что-то подобное.

С другой стороны, по крайней мере, вы получите больше практики, и вторая версия вашего скрипта Python, вероятно, будет намного лучше, чем первая!


1

Вы не указали, работаете ли вы на ПК или на сервере. Если ваши файлы хранятся на выделенном файловом сервере, то зачастую аппаратное обеспечение файлового сервера (ОС на нем) хранит автоматические резервные копии («снимки»).

Под линуксом

Виртуальный скрытый каталог снимков существует в каждом каталоге вашей файловой системы.

Пытаться:

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

Перейдите в любой каталог времени, который достаточно стар (до вашей ошибки перезаписи файла). Внутри каталога timepoint вы должны видеть состояние ../..каталога (и всех подкаталогов) на тот момент в прошлом.

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. Эти автоматические снимки представляют собой скользящую историю. Старые изменения в конце концов проваливаются и теряются. Вам нужно использовать эту технику как можно скорее после того, как вы поймете, что вам нужен файл обратно.

Под виндой

Каталог скрытых снимков может называться ~ снимок и существовать только на корневом уровне данного диска.

Совет

Снимки - это защитная сеть, которая работает большую часть времени, но не каждый раз. Я согласен с другими рекомендациями использовать систему контроля версий (например, git) даже для тривиальных файлов.


1

Это было сказано ранее, и я скажу это снова. Используйте систему контроля версий.

Резервные копии предназначены для восстановления аппаратного сбоя. Управление ревизиями предназначено для таких ситуаций, как ваша (и имеет много других применений). Инструменты контроля версий позволяют вести историю файла и возвращаться к любой точке этой истории.

Примеры инструментов контроля версий включают в себя Subversion (SVN) (немного устаревший сейчас, но все еще хорошо работающий), Mercurial (HG) и GIT (GIT) (трудно использовать). svn хорош для офисных документов, а другие um-mergables, git и hg превзошли его для большинства других ролей. hg и git позволяют работать автономно и синхронизироваться с удаленным сервером для распространения и резервного копирования.

Прочтите информацию о контроле версий, затем распределите контроль версий и попробуйте их.


Я согласен с тем, что использование контроля версий лучше всего подходит для таких ситуаций, как у меня, но предоставление правильных разрешений файлам не менее важно
Бхарат Теджа,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.