Удалить длинную строку из файлов

В

ssh root@xxx.xxx.xxx.xx "sudo /etc/init.d/smokeping reload"

Ваша оболочка

(1) (или в Вашем примере оболочка, запущенная PHP's exec()) проанализирует ту командную строку и, если найдено выполнять a ssh

(2) Команда, которая свяжется с a sshd

(3) Сервер на xxx.xxx.xxx.xx который после успешной аутентификации назовет a shell

(4) Который интерпретирует это sudo командная строка и выполненный sudo

(5) Команда, которую после проверки полномочий выполнит /etc/init.d/smokeping

(6) Который самостоятельно является, вероятно, сценарием оболочки, который выполняет несколько команд.

Несколько вещей могут перестать работать там. Если все шаги один к 5 успешны, то статус выхода /etc/init.d/smokeping будет сообщаться Вашей оболочке потому что sudo действительно сообщает статус выхода команды, которую он выполняет и удаленные выходы оболочки со статусом выхода последней команды, которую он выполнил и ssh сообщает статус выхода удаленной оболочки.

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

В Вашем случае, также /etc/init.d/smokeping решенный, что независимо от того, что ошибка произошла, был недостаточно для гарантирования ненулевого статуса выхода, или тот сценарий не записан правильно и не удается возвратиться с ненулевым статусом выхода на отказ (или некоторый патологический случай, включающий недостойное поведение или неверную конфигурацию ssh, sudo или удаленная оболочка).

/etc/init.d сценарии часто пишутся с set -e. С тем включенным флагом оболочка, интерпретирующая сценарий, будет выходом по умолчанию, когда команда, это выполняет сбои (с ненулевым статусом выхода провальной команды), который заставляет меня думать здесь, что мы можем быть в первой ситуации: "smokeping" действительно решает сообщить, что он успешно перезагрузил.

Пример патологического случая мог быть, например: bash используемый в качестве удаленной оболочки (bash действительно читает ~/.bashrc при вызове ssh даже при том, что это не интерактивные оболочки), и ~/.bashrc имеет что-то как:

trap 'whatever...; exit 0' EXIT

Который вызвал бы статус выхода интерактивных оболочек или оболочек, запущенных ssh или rsh всегда быть 0.

4
13.10.2015, 23:23
3 ответа

Хорошо, так как по какой-то причине использование переменной для хранения местоположения не работает, я думаю, что лучшим методом в целом было бы использовать find , чтобы просто найти, где существует Symantec, то вы можете cat это не проблема и повторять весь путь.

for i in `cat /app/scripts/symantec_scripts/list`
do ssh root@$i "uname -n
cat $(find / -maxdepth 2 -name Symantec)/virusdefs/definfo.dat
echo Location is $(find / -maxdepth 2 -name Symantec)/virusdefs/definfo.dat
echo ....................................................................."
done | tee /tmp/symantec_info.`date +"%m%d%y"`

В основном $ (команда) выполняет команду так, как если бы она была в оболочке, и заменяет ее выводом, поэтому $ (find/-maxdepth 2 -name Symantec) выглядит, начиная с /, и только углубленно опускается 2 каталоги, для чего-либо с именем Symantec, и выводит его. Этот вывод просто используется вместо всего оператора $ (command).

Вся инструкция $ (найти...) в вашем случае должна выводить что-то вроде /app/Symantec или /opt/Symantec

Это также имеет дополнительное преимущество, так как позволяет избежать длинной инструкции , если , и найти Symantec, если она будет где-либо еще.

Единственный недостаток состоит в том, что по какой-либо причине у вас есть несколько каталогов Symantec в непосредственном корневом каталоге и любой каталог с уровнем выше /. Это вызовет проблемы.

-121--133068-

Недавно я также испытал эту проблему.

Исправлено путем изменения разрешений каталога $ HOME . Однако простой запуск chmod g-w ~/ не исправил проблему. В дополнение к chmod g-w ~/ Мне также нужно было изменить разрешения других в каталоге $ HOME , запустив chmod o-wx ~/

Вместе:

chmod g-w ~/
chmod o-wx ~/

Обратите внимание, что я не уверен, что o-x был необходим, я просто запустил его в качестве предварительного

-121--16098-

Попробуйте с помощью fgrep или, эквивалентно, grep -F . Это интерпретирует образец как фиксированный ряд.

Можно также поместить эту строку в файл (самостоятельно) и использовать grep -f filename для указания файла. Хотя флаг -F по-прежнему необходим.

Другие варианты см. в man grep ; Есть несколько, которые могут быть полезны.

Для получения информации о различных способах удаления строки, соответствующей заданному образцу, см. https://stackoverflow.com/a/5413132/5419599 .

Один из подходов состоит в следующем:

  1. Поместите эту строку текста в файл самостоятельно. Назовите его «шаблонный файл».
  2. Запустите файл шаблона grep -lrFf. > filelist
  3. Отредактируйте filelist для удаления строки ./patternfile
  4. Выполните для i в $ (cat filelist); do grep -vf patternfile $ i > temp & & chmod --привязка = $ i temp & & mv temp $ i; done

На этапе 2 опциями grep являются: -l для перечисления соответствующих файлов; -r для рекурсии в подкаталоги; -F для использования фиксированной последовательности в качестве образца для сопоставления; -f для использования файла patternfile в качестве образца для сопоставления;затем, конечно, > список файлов для создания файла, содержащего список совпадающих файлов.

На шаге 4 grep просто использует флаг -v для печати не соответствующих строк, а затем chmod гарантирует отсутствие проблем с разрешениями, и mv возвращает файл на место.

Могут быть лучшие способы, но я думаю, что этого будет достаточно.

EDIT: Если вы выполняете это как root , а не все эти файлы принадлежат root, выполните следующую пересмотренную версию шага 4:

for i in $(cat filelist) ; do grep -vf patternfile $i > temp && chown --reference=$i temp && chmod --reference=$i temp && mv temp $i ; done

Исходный шаг 4 подходит, если вы являетесь владельцем всех файлов.

2
27.01.2020, 20:50

Предполагая, что у вас есть приличные соглашения по кодированию, просто удалите любую строку больше определенного размера:

shopt -s extglob nullglob
sed -i.bak -r '/.{10000}/d' **/*.php

для @wildcard:

find . -name '*.php' -print0 | while IFS= read -rd "" file; do
    before=$(wc -l < "$file")
    after=$(sed -r '/.{10000}/d' "$file" | wc -l)
    case $(( diff = before - after )) in
        0) :;;  # no-op
        *) echo "will remove $diff lines from $file";;
    esac
done
5
27.01.2020, 20:50

Предполагая, что эта строка довольно уникальна в ваших файлах, вы можете использовать некоторые regex, чтобы найти несколько заметных частей строки и find с sed replace, чтобы заменить их

 find . -name "*.php" -exec sed -i 's/?php.*strtolower.*qhroczocgv.*boxknervrr.*-1; ?>//g' {} \;

Это оставит пустую строку на своем месте.

Знаете ли вы, будет ли эта строка единственной в строке, в которой она присутствует? Если да, то вы можете попробовать сократить ее с помощью:

find . -name "*.php" -exec sed -i 's/?php.*strtolower.*qhroczocgv.*boxknervrr.*-1; ?>//g' {} \;

Которая будет искать строку, содержащую php, любое количество других символов, за которой следует strtolower, любое количество других символов, за которым следует qhroczocgv, за которым следует любое количество других символов, за которым следует boxknervrr, за которым следует любое количество других символов, а затем удаляет всю строку.

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

0
27.01.2020, 20:50

Теги

Похожие вопросы