Труба к моему собственному сценарию

Я недавно заметил это сообщение от grep

"grep: warning: GREP_OPTIONS is deprecated; please use an alias or script" 

Я получаю это предупреждение, потому что –color = всегда определено в моем файле .bashrc. Альянс AFAIK нецелесообразен, потому что я хочу, чтобы это работало на трубе. Например,

 echo "abc" |grep b 

следует выделить b. Поскольку псевдоним не будет работать, другим вариантом является создание сценария. Но как заставить скрипт принимать входные данные из канала? В этом случае я хочу, чтобы скрипт добавлял –color = always.

РЕДАКТИРОВАТЬ: Псевдоним работает все-таки … и так делает скрипт. Я понятия не имею, что я делаю неправильно с методом псевдонима. Однако при создании сценария обязательно укажите $ 1 для входного параметра.

Для всех, кто хочет знать, как подключиться к вашему сценарию, в этом примере он работал для меня, выполняя следующие действия:

сначала сделайте скрипт в месте пути, чтобы его исполняемый файл, например

 # ~/.bin/testgrep grep --color=always $1 

Теперь сделайте исполняемый файл сценария, например

 chmod +x ~/.bin/testgrep 

Теперь это должно сработать!

2 Solutions collect form web for “Труба к моему собственному сценарию”

grep (т. е. /bin/grep ) будет считываться со стандартного ввода, если он вызывается без аргументов имени файла. Так что просто написать скрипт, который запускает grep со входом со стандартного ввода – просто вызовите grep без аргументов имени файла. Но grep должен быть предоставлен (по крайней мере) один аргумент PATTERN (или эквивалент). Крайне негибкий способ сделать это, что вряд ли будет очень полезным в реальной жизни, состоит в том, чтобы жестко закодировать строку поиска (шаблон) в ваш скрипт grep; например,

 #!/bin/sh grep --color=always cat 

которые могут быть использованы в контексте

 ps | mygrep 

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

 #!/bin/sh grep --color=always $USER 

которые могут быть использованы в контексте

 ps -ef | mygrep 

и, вероятно, не намного больше. Единственное разумное, реалистичное, надежное решение – позволить пользователю скрипта предоставить строку поиска в качестве аргумента командной строки:

 #!/bin/sh grep --color=always $1 

которые могут быть использованы в контексте

 dmesg | mygrep TCP 

и на самом деле может быть довольно полезным.

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

  mygrep -i tcp Нечувствительный к регистру поиск;  найти tcp , TCP , Tcp и т. д.
 mygrep -v bash Найдите все, кроме bash .
 mygrep -e cat -e dog Найдите каждую строку, содержащую кошку или собаку .
 mygrep -f wordlist Строки поиска находятся в файле. 

Таким образом, второй проект нашего скрипта может быть:

 #!/bin/sh grep --color=always $1 $2 $3 $4 $5 $6 $7 $8 $9 

который может обрабатывать любой из приведенных выше примеров. В качестве дополнительного бонуса это не нужно использовать для чтения стандартного ввода; мы можем сказать

 mygrep -i path .bashrc 

и он будет работать

 grep --color=always -i path .bashrc 

Но мы еще не закончили! Рассматривать

 mygrep "cat food" "shopping list.txt" 

который будет работать

 grep --color=always cat food shopping list.txt 

который (попытается) найти cat в трех файлах: food , shopping и list.txt . Хорошо, мы можем справиться с этим, сказав

 #!/bin/sh grep --color=always "$1" "$2" 

но

 #!/bin/sh grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" 

не является хорошим ответом; он превратится

 mygrep "cat food" "shopping list.txt" 

в

 grep --color=always "cat food" "shopping list.txt" "" "" "" "" "" "" "" 

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

Итак, что делать, что делать? Подожди; У меня есть кувалда в моем шкафуте:

 #!/bin/sh if [ "$1" = "" ] then printf "%s\n" "error: mygrep must be run with at least one argument." elif [ "$2" = "" ] then grep --color=always "$1" elif [ "$3" = "" ] then grep --color=always "$1" "$2" elif [ "$4" = "" ] then grep --color=always "$1" "$2" "$3" elif [ "$5" = "" ] then grep --color=always "$1" "$2" "$3" "$4" elif [ "$6" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" elif [ "$7" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" elif [ "$8" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" elif [ "$9" = "" ] then grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" else grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" fi 

Правильно.

  1. Это смехотворно непрактично.
  2. Даже это не удается

     mygrep -e cat -e dog -e fish file1 file2 file3 file4 

    потому что он содержит более девяти аргументов! И, хотя эта ситуация может показаться маловероятной, та же проблема возникает

     mygrep bird * 

    если в текущем каталоге содержится более восьми (не скрытых) файлов.

Итак, что делать, что делать?

TL; DR

Если вы посмотрите в bash (1) в разделе « Специальные параметры» , вы увидите, что $@ расширяется до списка позиционных параметров, начиная с одного. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. То есть, "$@" эквивалентно "$1" "$2" … (как реализовано в длинном скрипте выше, но не ограничиваясь первыми девятью). Итак, способ написать сценарий для обертывания (т. Е. Действовать как интерфейс для) для некоторой команды, действующей как псевдоним, является

 #!/bin/sh grep --color=always "$@" 

Псевдоним будет работать. У меня grep aliased grep --color=auto :

 % which grep grep: aliased to grep --color=auto 

И у трубопровода для grep есть поведение, которое вы желаете:

введите описание изображения здесь

  • Как сделать скрипт sudo без пароля для любого пользователя в bash
  • Умножение и добавление Баша
  • Гибридный код в сценариях оболочки. Обмен переменными
  • Почему мой скрипт медленно использует все больше и больше памяти? Это из-за мидори?
  • Как выводить некоторые данные в разные ячейки файла Excel?
  • Как скопировать / объединить два каталога, и если два файла имеют одинаковое имя, переименуйте более старый, добавив время его модификации
  • Сценарий оболочки: если несколько условий
  • В чем разница между ./script и. ./script?
  • Как форматировать textutil -excludedelements
  • Запустить скрипт на нескольких оболочках?
  • ошибка при замене нескольких слов в строке с помощью sed
  • Interesting Posts

    «Пакет« dconf-cli »не имеет кандидата на установку»

    Экран GNU: эквивалент соответствия в tmux

    Значение по умолчанию iterface / routes в Linux

    проблемы печати с принтером DDST (aka PCL6) RICOH Aficio SP C240DN

    Как настроить сокет для opendkim на Debian Testing / Stretch

    Как выполнить обратный поиск истории в vi-режиме ZSH?

    Помогите мне понять владельца переменной места для команды curl в Dockerfile

    Разный цвет для диапазона KiB в `ls -l`

    Клиент OpenVPN получает новый ip для каждой загрузки, как получить тот же адрес в x время ожидания?

    Port Mirroring с использованием iptables – копирование всего трафика между nginx на: 80 и Apache по: 8080

    ошибка при загрузке разделяемых библиотек: libboost_thread.so.1.54.0: невозможно открыть файл общих объектов: такой файл или каталог отсутствует

    Функция System () с использованием Octave

    Не удается установить и использовать драйверы nvidia (Wheezy)

    MongoDB не удалит

    Построить модуль из другого ядра

    Linux и Unix - лучшая ОС в мире.