Почему моя команда не работает при наличии псевдонима?

Почему моя команда не работает при наличии псевдонима?

Я использую ps -ef | grep catalina | grep -v grepдля вывода процесса tomcat, запущенного в системе:

kshitiz   7099     1  0 May11 ?        00:02:29 /usr/lib/jvm/jdk1.8.0/bin/java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:38156 -Dcatalina.base=/home/kshitiz/Documents/workspaces/ggts/.metadata/.plugins/org.eclipse.wst.server.core/tmp1 -Dcatalina.home=/opt/tomcat-7.0.42 -Dwtp.deploy=/home/kshitiz/Documents/workspaces/ggts/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps -Djava.endorsed.dirs=/opt/tomcat-7.0.42/endorsed -Dfile.encoding=UTF-8 -classpath /opt/tomcat-7.0.42/bin/bootstrap.jar:/opt/tomcat-7.0.42/bin/tomcat-juli.jar:/usr/lib/jvm/jdk1.8.0/lib/tools.jar org.apache.catalina.startup.Bootstrap start

Затем я использую ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}'для извлечения идентификатора процесса:

7099

Но когда я создаю псевдоним для всей команды alias tomcat_id="ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}'"и использую ее через псевдоним, она печатает весь текст и, awkпохоже, не работает.

type tomcat_idдает:

tomcat_id is aliased to `ps -ef | grep catalina | grep -v grep | awk -F' ' '{print }''

решение1

Общее правило псевдонимов: если псевдоним слишком сложен, используйте вместо него функцию.

tomcat_id () {
  ps -ef | grep catalina | grep -v grep | awk -F' ' '{print $2}'
}

Проблема с определением псевдонима в том, что вы неправильно цитируете. Строка, определяющая псевдоним, является командой оболочки и анализируется оболочкой. Поскольку вы использовали двойные кавычки, а позиционных параметров в то время, вероятно, нет (поэтому $2расширяется до пустой строки), псевдоним, который вы определили, будет

ps -ef | grep catalina | grep -v grep | awk -F' ' '{print }'

Самый простой способ определить псевдоним — использовать одинарные кавычки для определения и избегать использования одинарных кавычек в команде aliased. Пока я этим занимаюсь, я удалил -F " ", который в любом случае является значением по умолчанию (и немного странным, потому что выглядит как «пробел», но означает «любая последовательность пробелов»).

alias tomcat_id='ps -ef | grep catalina | grep -v grep | awk "{print \$2}"'

Или вы можете использовать '\''для эффективного заключения в кавычки одинарную кавычку внутри литерала, заключенного в одинарные кавычки.

alias tomcat_id='ps -ef | grep catalina | grep -v grep | awk '\''{print \$2}'\'

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

alias tomcat_id='pgrep catalina'

или

alias tomcat_id='pidof catalina'

решение2

Ответ Гноука совершенно верен (именно поэтому я его и поддержал), но я хотел бы предложить альтернативу:

alias tomcat_id="ps -ef|awk '\$8 ~ /java/ && /catalina/ {print \$2}'"

Идея здесь в том, что в имени процесса (поле 8) мы должны иметь возможность найти javaи в строке в целом мы должны найти catalina.

Поэтому мы позволяем awkделать всю работу по сопоставлению и печати. ​​Не нужно беспокоиться grep;)

Итак, значение:

$8 ~ /java/ && /catalina/ {print $2}

сопоставляет поле $8с регулярным выражением /java/и сопоставляет всю строку (можно также использовать $0явно) с регулярным выражением, /catalina/и если эти вещи верны, выводит поле $2. Помните, что уже было сказано в ответе Gnouc: разделитель по умолчанию уже является пробелом. Нет необходимости определять это.

решение3

Вам необходимо экранировать знак доллара в awkкоманде:

alias tomcat_id="ps -ef | grep catalina | grep -v grep | awk '{print \$2}'"

И вам не обязательно использовать пробелы -F' ', awkиспользуйте их как разделитель полей по умолчанию.

Связанный контент