Это - то, как я закончил тем, что делал его.
Я создал файл /etc/sudoers.d/dev
Содержа:
# allow user dev to become user tomcat
# invoked with [dev@host ~]$ sudo su - tomcat
dev ALL = (root) NOPASSWD: /bin/su - tomcat
измененный полномочия файла с chmod 0440 /etc/sudoers.d/dev
созданный псевдоним в dev's .bashrc
alias tomcat='sudo su - tomcat'
Это приводит к способности к dev пользователю стать пользователем кота или без имеющий необходимость ввести (или без действительно имеющий) пароль когда-либо путем ввода tomcat
в командной строке.
Вы путаете два совсем других типа исходных данных.
stdin
)Они отличаются, и полезны для различных целей. Некоторые команды могут взять вход обоими способами, но они обычно используют их по-другому. Возьмите, например, wc
команда:
Проходить мимо входа stdin
:
ls | wc -l
Это будет считать строки в выводе ls
Передача, введенная параметрами командной строки:
wc -l $(ls)
Это будет считать строки в списке файлов распечатанными ls
Совершенно другие вещи.
Для ответа на вопрос это кажется, что Вы хотите получить уровень от вывода первой команды и затем использовать уровень в качестве параметра командной строки для второй команды. Вот один способ сделать это:
rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"
Объяснение sed
:
s/pattern/replacement/
команда должна заменить некоторый шаблон^rate
) сопровождаемый любыми двумя символами (..
), сопровождаемый 0 или больше цифрами, сопровождаемыми a %
, сопровождаемый остальной частью текста (.*
)\1
в замене означает контент первого выражения, полученного в \(...\)
, так в этом случае цифры перед %
знак-n
флаг sed
управляйте средствами не распечатать строки по умолчанию. p
в конце s///
управляйте средствами распечатать строку, если была замена. Короче говоря, команда распечатает что-то, только если было соответствие.Моделировать вывод command1
Я использую этот оператор эха:
$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'
Быстрый тест:
$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag
Это - вся польза, поэтому позволяет, анализируют его:
$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps
Таким образом, мы получаем строку, мы хотим из command1
, позволяет передаче это в command2
:
$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps
Я ожидаю "rate was "$(command1 | grep 'rate')
конкатенировать автоматически. Если это не работает из-за пробела, необходимо смочь передать вход как так вместо этого:
$ alias command2='echo'
$ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"')
-t="rate was rate (10%) - name: value - 10Kbps "
Первая задача состоит в том, чтобы извлечь уровень из той строки. С GNU grep (не встроил Linux или Cygwin), можно использовать -o
опция. Часть, которую Вы хотите, является одной содержащей только цифры, и сопровождаемый a %
знак. Если Вы не хотите извлекать %
самостоятельно, Вам нужен дополнительный прием: утверждение предвидения нулевой ширины, которое соответствует только, только если это ничто не сопровождается %
.
command1 -p=aaa -v=bbb -i=4 | grep -o -P '[0-9]+(?=%)'
Другая возможность состоит в том, чтобы использовать sed. Для извлечения части строки в sed используйте s
команда, с regex, который соответствует целой строке (запускающийся с ^
и окончание $
), с частью для сохранения в группе (\(…\)
). Замените целую строку содержанием группы (групп) для хранения. В целом передайте -n
опция выключить печать по умолчанию и поместить p
модификатор для печати строк, где существует что-то для извлечения (здесь существует одна строка, таким образом, это не имеет значения). Посмотрите Возврат только часть строки после шаблона соответствия и Извлечения regex, соответствовавшего 'sed', не печатая окружающие символы для большего количества приемов sed.
command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$/\1/'
Более гибкий снова, чем sed, awk. Awk выполняет инструкции для каждой строки на маленьком императивном языке. Существует много способов извлечь уровень здесь; я выбираю вторые поля (поля разграничены пробелом по умолчанию), и удалите все символы в нем, которые не являются цифрой.
command1 -p=aaa -v=bbb -i=4 | awk '{gsub(/[^0-9]+/, "", $2); print $2}'
Следующий шаг, теперь, когда Вы извлекли уровень, должен передать его как аргумент command2
. Инструмент для этого является командой susbtitution. Если Вы вставляете команду $(…)
(долларовая круглая скобка), ее выводом заменяют в командную строку. Вывод команды разделяется на отдельные слова в каждом пробельном блоке, и каждое слово рассматривают как подстановочный шаблон; если Вы не хотите, чтобы это произошло, поместите двойные кавычки вокруг замены команды: "$(…)"
. С двойными кавычками вывод команды используется непосредственно в качестве единственного параметра (единственное преобразование состоит в том, что новые строки в конце вывода удалены).
command2 -t "$(command1 -p=aaa -v=bbb -i=4 |
sed 's/^.*rate(\([0-9]*\)%).*$/\1/')"
Можно использовать grep
и это - PCRE - Perl Совместимые Регулярные выражения. Это позволяет Вам использовать lookbehind для соответствия значению уровня без включения строки "уровень" в результатах при захвате для него.
$ echo "rate (10%) - name: value - 10Kbps" | grep -oP '(?<=^rate \()\d+'
10
Вышеупомянутое grep
работы следующим образом:
-o
возвратит только, что мы ищем, \d+
, который является цифрами в parens.-P
активирует опцию PCRE grep(?<=^rate \()
будет только возвращаемые строки, которые начинаются "с уровня ("Для ловли значения "уровня", можно работать command1
как так:
$ rate=$(command 1 | grep -oP '(?<=^rate \()\d+'
Затем для Вашей 2-й команды Вы просто использовали бы ту переменную.
$ command2 -t=${rate}
Вы могли стать необычными и сделать ту всю одну строку:
$ command2 -t=$(command1 | grep -oP '(?<=^rate \()\d+')
Это выполнит command1 в $(..)
блок выполнения, возьмите его результаты и включайте их в command2 -t=..
переключатель.
Обычно я использую это:
command1 | xargs -I{} command2 {}
Передайте вывод command1
через xargs, заменив (фигурные скобки )на command2
. Если команда1 равна find
, обязательно используйте -print0
и добавьте -0
к xargs
для строк с завершающим нулем, а xargs
будет вызывать command2
для каждой найденной вещи.
В вашем случае (и взятие строки sed от @Janos):
command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p' | xargs -I{} command2 -t="rate was {}"
Обычно я использую `команду `, чтобы поместить ее вывод в качестве аргумента другой команды. Например, чтобы найти ресурсы, потребляемые процессом foo на freebsd, будет:
procstat -r `pgrep -x foo`
Здесь pgrep используется для извлечения PID процесса foo, который передается команде procstat, которая ожидает PID процесса в качестве аргумента.