Отфильтровать недопустимые PID переносимо - PullRequest
3 голосов
/ 21 июня 2020

Я написал сценарий для получения PID сеанса верхнего уровня, то есть инициатора сеанса, который может быть оболочкой, например bash, da sh, k sh или даже systemd. Сценарий может получить PID в качестве начального параметра, однако мне нужно отфильтровать его, чтобы проверить, что это действительное целое число, а не что-то вроде 34fg45, -5467, и я не хочу, чтобы он начинался с нуля, например 05467.

Это фрагмент скрипта.

if [ "$1" != "" ]; then
    if [[ "$1" == [1-9]*([0-9]) ]]; then                <- Check for Integer; error here in non bash shell 
        if ps -p $1 -o "pid=" >/dev/null 2>&1; then
            pid=$1
        else
            echo "PID $1, no such process." >&2
            exit 1
        fi
    else
        echo "Invalid pid." >&2
        exit 1
    fi
else
    pid=$$
fi

Код работает в bash, но не запускается на da sh с синтаксической ошибкой:

./tspid: 16: ./tspid: Syntax error: "(" unexpected (expecting "then")

Насколько я понимаю,

if [[ "$1" =~ ^[0-9][1-9]*$ ]]; с использованием =~ выполняет сопоставление регулярных выражений, и if [[ "$1" == [1-9]*([0-9]) ]]; при использовании == выполняется сопоставление с образцом

  1. Верно?
  2. Как преобразовать приведенные выше выражения для работы в обоих, не bash, а также в bash снаряды?

1 Ответ

6 голосов
/ 21 июня 2020

Используйте условную конструкцию case . Он есть в каждой оболочке POSIX, и, в отличие от двойных скобок, он не выглядит ужасно.

# make sure 0-9 is literally 0 to 9
LC_COLLATE=C
# assume set -u is not in effect or $1 is set
case $1 in
('')
  # handle empty argument
  ;;
(0*|*[!0-9]*)
  # handle invalid PID (0, 042, 42a, etc.)
  ;;
(*)
  # handle valid PID
  ;;
esac
# restore LC_COLLATE if necessary
...