2

Hello everyone and thanks for your support!

I'm facing a problem while using REGEX inside a bash script through =~ operand.

Environment: GNU bash, version 4.1.7(1)-release (powerpc-ibm-aix5.1.0.0)

bash-4.1$ if [[ a =~ a ]]; then echo match; fi
Segmentation fault(coredump)

The bash version:

bash-4.1$ bash --version
GNU bash, version 4.1.7(1)-release (powerpc-ibm-aix5.1.0.0)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

I'm looking for the best way to identify if a given argument is an integer because I need to be sure the given argument is a PID (process id) In Linux i always use =~

I have not been able to find solutions. I've searched online but can't find anything similar.

Thank you in advance

12
  • How did you test bash version? Commented Feb 28, 2024 at 11:51
  • I just did this: bash-4.1$ bash --version GNU bash, version 4.1.7(1)-release (powerpc-ibm-aix5.1.0.0) Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. bash-4.1$ Commented Feb 28, 2024 at 11:58
  • Please add this to the question @omar.c. Commented Feb 28, 2024 at 12:04
  • I'm looking for the best way to identify if a given argument is an integer because I need to be sure the given argument is a PID (process id) Commented Feb 28, 2024 at 12:05
  • 2
    Does it also need to be a valid current pid? You might as well just ask ps -p "${a}" &> /dev/null and test exit status ${?}. Commented Feb 28, 2024 at 12:52

1 Answer 1

0

If possible, I'd use other means than bash-testing $pid.

I'd use kill or awk instead:

1 - to just check if $pid is a (valid, running) process on AIX:

kill -s 0 -- "$pid" && echo "pid $pid is a running process"

Note: this will NOT kill the process, signal 0 just works if the $pid exist.

However (thanks to @ChrisDavies for pointing it out in the comments!) : "... you must be the owner of the process (or root) to avoid getting an Operation not permitted error"

2 - if you are unsure wheter you got the correct column (This happens a lot with ps output, as the first column (USER) can start with a space or not depending on the username's length):

you probably need to add a space BEFORE the input line:

ps ... | sed -e 's/^/ /' | awk -v pid="$pid" ' something on column $pid '

: this will help awk (and sort and everything else) to not mitakenly see some pid in the first or second column ($1 or $2) depending if the content of that "first" column started with a space or not.

3 - To avoid the problem altogether you could also use a custom ps : You still need the sed as shorter pid's will start with a space, and the longest ones will not!

ps -e -o 'pid, ppid, user, etime, args' \
| sed -e 's/^/ /' \
| awk '
  BEGIN {
      col_pid=1;  col_ppid=2; col_user=3; col_etime=4 start_args=5 
  }
  
  ( $col_pid !~ "/^[0-9]+$/ ) {
      print "line: " FNR " : column " col_pid " does NOT match a number? : \047" $col_pid "\047" 
  }
  '
# you could also do the sed part with awk, but it would : recompute $0, losing spacings
10
  • 1
    "signal 0 just works if the $pid exist" - and you must be the owner of the process (or root) to avoid getting an Operation not permitted error Commented Feb 28, 2024 at 13:40
  • Oh, very important precision indeed, thanks @ChrisDavies ! Commented Feb 28, 2024 at 13:41
  • 1
    You need a case statement to sort it out properly. For example, pid=28306; st=$(LANG=C kill -0 "$pid" 2>&1); ss=$?; case "$ss-$st" in 0-*) echo "Exists and is mine" ;; 1-*permitted) echo "PID $pid exists but not mine" ;; 1-*process) echo "PID $pid does not exist" ;; *) echo "Unsure about PID $pid: SS=$ss, ST=$st" ;; esac Commented Feb 28, 2024 at 14:02
  • 1
    Why do you need the space? Awk doesn't care, it collapses consecutive field separators. Try printf 'none\n one\n two\n three\n' | awk '{print ":"$1":"}'. And when could you have a PID that isn't numerical? There's no point in testing the ps output, the OP needed to test a variable to see if it could be a PID. Anything listed as a PID by ps will be a PID by definition, right? Commented Feb 28, 2024 at 15:28
  • 1
    Ah yes, but that is because you are using a regex, so you are explicitly telling awk to do this. It isn't needed if you don't use a regex. Commented Feb 29, 2024 at 11:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.