Вывод канала для использования в качестве поисковой спецификации для grep на Linux

Внимание: примерный код этого ответа (например, примерный код вопроса) использует расширение PHP mysql, которое устарело в PHP 5.5.0 и полностью удалено в PHP 7.0.0.

Если вы используете последнюю версию PHP, опция mysql_real_escape_string, описанная ниже, больше не будет доступна (хотя mysqli::escape_string является современным эквивалентом). В настоящее время опция mysql_real_escape_string имеет смысл только для устаревшего кода на старой версии PHP.


У вас есть два варианта - экранирование специальных символов в вашем unsafe_variable или использование параметризованный запрос. Оба будут защищать вас от SQL-инъекций. Параметрированный запрос считается лучшей практикой, но для его использования потребуется переходить на более новое расширение mysql в PHP.

Мы рассмотрим нижнюю строку удара, которая будет первой.

//Connect

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");

//Disconnect

См. также информацию о функции mysql_real_escape_string .

Чтобы использовать параметризованный запрос, вам нужно использовать MySQLi , а не функции MySQL . Чтобы переписать ваш пример, нам понадобится что-то вроде следующего.

prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();
?>

Ключевая функция, которую вы хотите прочитать, будет mysqli::prepare .

Также, как предложили другие, вы можете сочтет полезным / легче повысить уровень абстракции с помощью чего-то вроде PDO .

Обратите внимание, что случай вы спросили об этом довольно просто, и что более сложные случаи могут потребовать более сложных подходов. В частности:

  • Если вы хотите изменить структуру SQL на основе пользовательского ввода, параметризованные запросы не помогут, и требуемое экранирование не распространяется на mysql_real_escape_string. В этом случае вам лучше было бы пропускать вход пользователя через белый список, чтобы обеспечить доступ только «безопасных» значений.
  • Если вы используете целые числа от пользовательского ввода в состоянии и берете mysql_real_escape_string, вы столкнетесь с проблемой, описанной в Polynomial в комментариях ниже. Этот случай более сложный, поскольку целые числа не будут окружены кавычками, поэтому вы можете иметь дело с проверкой того, что пользовательский ввод содержит только цифры.
  • Есть, вероятно, другие случаи, о которых я не знаю. Вы можете найти , этот является полезным ресурсом для некоторых более тонких проблем, с которыми вы можете столкнуться.
27
задан Peter Mortensen 21 November 2014 в 12:05
поделиться

5 ответов

При использовании Bash тогда можно использовать обратные галочки:

> grep -e "`grep ... ...`" files

эти -e флаг и двойные кавычки там, чтобы гарантировать, что любой вывод от начальной буквы grep, который запускается с дефиса, тогда не интерпретируется как опция к второму grep.

Примечание, что двойной прием заключения в кавычки (который также гарантирует, что вывод от grep рассматривают как единственный параметр) только работает с Bash. Это, кажется, не работает с (t) csh.

Примечание также, что обратные галочки являются стандартным способом получить вывод из одной программы в список параметров другого. Не все программы имеют удобный способ считать параметры из stdin способ, которым (f) делает grep.

8
ответ дан Alnitak 28 November 2019 в 05:24
поделиться

Попробуйте

grep ... | fgrep -f - file1 file2 ...
12
ответ дан Paul Tomblin 28 November 2019 в 05:24
поделиться

Я хотел найти текст в файлах (используя grep), которые имели определенный шаблон в именах файлов (найденный с помощью find) в текущем каталоге. Я использовал следующую команду:

 grep -i "pattern1" $(find . -name "pattern2")

Здесь pattern2 - шаблон в именах файлов, а pattern1 - шаблон, который ищется в файлах, соответствующих pattern2 .

Редактировать: Не строго по трубам, но все еще связаны и весьма полезны ...

4
ответ дан mcvz 28 November 2019 в 05:24
поделиться

Ладно, нарушая правила, так как это не ответ, просто замечание, что я не могу заставить работать ни одно из этих решений.

% fgrep -f test file

отлично работает.

% cat test | fgrep -f - file
fgrep: -: No such file or directory

не удается.

% cat test | xargs -ifoo grep foo file 
xargs: illegal option -- i
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]

не удается. Обратите внимание, что заглавная буква I необходима. Если я использую это все хорошо.

% grep "`cat test`" file

своего рода работает в том, что возвращает строку для совпадающих терминов, но также возвращает строку grep: line 3 in test: No such file or directory для каждого файла, который не находит соответствия.

Я что-то упустил или это просто различия в моем дистрибутиве Дарвина или в оболочке bash?

1
ответ дан SidMuchRock 28 November 2019 в 05:24
поделиться

Вам необходимо использовать переключатель -i xargs -i :

grep ... | xargs -ifoo grep foo file_in_which_to_search

Это принимает вариант после -i ( foo в данном случае) и заменяет каждое его вхождение в команду выводом первого grep .

Это то же самое, что:

grep `grep ...` file_in_which_to_search
14
ответ дан 28 November 2019 в 05:24
поделиться
Другие вопросы по тегам:

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