Як витягує статус виходу команди у змінну?


14

Я почав вивчати Баша пару днів тому.

Я намагаюся отримати вихідний grepвираз вираження в такій змінній:

check=grep -ci 'text' file.sh

і результат, який я отримав, - це

No command '-ic' found

Чи потрібно це робити з командою pipe?


6
Стан виходу можна перевірити $?відразу після завершення команди.
coffeMug

і ви можете вивчити масив PIPESTATUS, якщо вам потрібно статус однієї з команд у конвеєрі.
cas

Відповіді:


26

Ваша команда,

check=grep -ci 'text' file.sh

буде інтерпретуватися оболонкою як "запустити команду -ciз аргументами textта file.shі встановити змінну checkзначенню grepв її середовищі".


Оболонка зберігає у змінній значення виходу останньо виконаної команди ?. Ви можете призначити його значення одній із власних змінних на зразок цієї:

grep -i 'PATTERN' file
check=$?

Якщо ви хочете скористатися цим значенням, ви можете скористатися checkзмінною:

if [ "$check" -eq 0 ]; then
    # do things for success
else
    # do other things for failure
fi

або ви можете пропустити за допомогою окремої змінної та переглядати $?всі разом:

if grep -q -i 'pattern' file; then
  # do things (pattern was found)
else
  # do other things (pattern was not found)
fi

(зауважте -q, він вказує grepнічого не виводити і виходити, як тільки щось відповідає; нас не дуже цікавить, які збіги тут)

Або, якщо ви просто хочете "робити речі", коли шаблон не знайдено:

if ! grep -q -i 'pattern' file; then
  # do things (pattern was not found)
fi

Збереження $?в іншу змінну потрібне лише тоді, коли вам доведеться використовувати її пізніше, коли значення в $?було перезаписано, як у

mkdir "$dir"
err=$?

if [ "$err" -ne 0 ] && [ ! -d "$dir" ]; then
    printf 'Error creating %s (error code %d)\n' "$dir" "$err" >&2
    exit "$err"
fi

У наведеному вище фрагменті коду $?буде перезаписано результат [ "$err" -ne 0 ] && [ ! -d "$dir" ]тесту. Збереження його тут дійсно необхідне лише в тому випадку, якщо нам потрібно його відобразити та використовувати exit.


4

Ваше запитання незрозуміле, але виходячи з поданого вами коду, схоже, що ви хочете, щоб змінна checkзберігала статус виходу grepкоманди. Спосіб зробити це - бігти

grep -ci 'text' file.sh
check=$?

При виконанні команди з оболонки, її статус виходу стає доступним через спеціальний параметр оболонки $?.

Це документується POSIX (стандарт для операційних систем, схожих на Unix) у його специфікації для оболонки, а реалізація Bash задокументована у Спеціальних параметрах .

Оскільки ви новий навчається, я настійно рекомендую почати з хорошої книги та / або онлайн-підручника, щоб отримати основи. Рекомендації щодо зовнішніх ресурсів не рекомендуються на сайтах Stack Exchange, але я б запропонував Lhunath та GreyCat's Bash Guide .


4

Ви сказали bash встановити змінну check=grepв середовищі, яке вона передає команді

-ci 'text' file.sh

але ciне існує.

Я вважаю, що ви мали намір укласти цю команду в зворотні кліти або в круглі дужки, що передували знаку долара, кожен з яких присвоїв би підрахунку, скільки рядків «текст» було знайдено у файлі (регістр нечутливий) у файлі:

check=`grep -ci 'text' file.sh`

check=$(grep -ci 'text' file.sh)

Тепер $checkмає бути 0, якщо немає відповідних, або позитивним, якщо вони були.


1

Плутати, чому використовувати -c при перевірці виводу? Він використовується для перевірки, скільки разів щось узгоджується - не в тому, успішно це чи ні.

   -c, --count
          Suppress normal output; instead print a count of matching  lines
          for  each  input  file.  With the -v, --invert-match option (see
          below), count non-matching lines.  (-c is specified by POSIX.)

але в цьому прикладі

check="$(grep --silent -i 'text' file.sh; echo $?)"

Він не видає нічого, крім коду виходу, який потім повторюється. Це вихід, який використовує перевірка змінної. Я також віддаю перевагу тому, що це один рядок.

Ви можете замінити -silent на -q. Я використовую його, оскільки ви не зацікавлені в греп-випуску, тільки працював він чи ні.

   -q, --quiet, --silent
          Quiet;  do  not  write  anything  to  standard   output.    Exit
          immediately  with  zero status if any match is found, even if an
          error was detected.  Also see the -s  or  --no-messages  option.
          (-q is specified by POSIX.)

$ check=$(echo test | grep -qi test; echo $?) # check variable is now set
$ echo $check
0
$ check=$(echo null | grep -qi test; echo $?)
$ echo $check
1

1

Правильний спосіб присвоїти вихід команді grep змінній такий, як @ monty-harder згадується:

check=`grep -ci 'text' file.sh`
check=$(grep -ci 'text' file.sh)

Хоча для призначення статусу виходу цієї команди змінній, ви повинні використовувати параметр оболонки $?відразу після виконання команди, як показано нижче:

grep -ci 'text' file.sh
check=$?
echo $check
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.