Why does the "kill" command work differently in bash and zsh - linux

the -L flag provided in kill does not work in zsh.
When I run the command kill -L Using zsh the result is:
kill: unknown signal: SIGL
kill: type kill -l for a list of signals
Running kill -L Using bash gives the list of signal names as expected.
-L, --table
List signal names in a nice table.
Please help me understand why this inconsistency, and can it be "fixed"?

kill is a shell builtin for both zsh and bash, with different implementations and options on each. The zsh builtin does support the POSIX -l option for listing signals, but not the GNU -L extension.
You can always use /bin/kill to run the freestanding program version if you desire. On OSes with a GNU runtime, that'll also support -L.

Related

Monitoring all running process using strace in shell script

I want to monitor all the running processes using strace and when a process ends the output of the strace should be sent to a file.
And how to find every running proc PID. I also want to include process name in the output file.
$ sudo strace -p 1725 -o firefox_trace.txt
$ tail -f firefox_trace.txt
1725 would be the PID of the proccess you want to monitor (you can find the PID with "ps -C firefox-bin", for firefox in the example)
And firefox_trace.txt would be the output file !
The way to got would be to find every running proc PID, and use the command to write them in the output file !
Considering the doc,
-p pid
Attach to the process with the process ID pid and begin tracing. The
trace may be terminated at any time by a keyboard interrupt signal (
CTRL -C). strace will respond by detaching itself from the traced
process(es) leaving it (them) to continue running. Multiple -p options
can be used to attach to up to 32 processes in addition to command
(which is optional if at least one -p option is given).
Use -o to store the output to the file, or 2>&1 to redirect standard error to output, so you can filter it (grep) or redirect it into file (> file).
To monitor process without knowing its PID, but name, you can use pgrep command, e.g.
strace -p $(pgrep command) -o file.out
where command is your name of process (e.g. php, Chrome, etc.).
To learn more about parameters, check man strace.

which programs will the killall command kill?

How do I list which programs will be killed with a killall command before I run it?
I'm looking for a killall -dryrun java kind of command, which would list all java processes that would be killed by executing the killall java command.
You can use pgrep as follows to list the processes first:
pgrep -a java
Depending on the killall version used on your system killall -s might do the trick. E.g. this is the case at least on Mac OS X and FreeBSD
On other variants of killall -s SIGNAL is used to specify the signal to send. Killall is not part of UNIX/POSIX standard so implementations vary.

linux shell kill signal SIGKILL && KILL

I just written a shell script to control the start and stop of a module. Everything seems normal until I find the stop command result in something unexpected.
I use the command kill -s SIGKILL -- -gpid to kill a group of processes. I use the /bin/sh to run the command like this
/bin/sh -c "kill -s SIGKILL -- -gpid"
which replied the error
/bin/sh: line 0: kill: SIGKILL: invalid signal specification
Then I replaced the /bin/sh with /bin/bash, so the command is
/bin/bash -c "kill -s SIGKILL -- -gpid"
which replied nothing error. so I conclude the explanation that the difference between bash and sh cause the result. However, when I ls the /bin/sh, I found the /bin/sh is a symbolic link to /bin/bash, so the command should be the same.
I found the command syntax kill -s SIGKILL is not in the syntax recommended, kill -s KILL recommended.
so I replaced the SIGKILL with KILL, the command is
/bin/sh -c "kill -s KILL -- -gpid"
which replied nothing error. as described above, anyone could explained this case.
The only truly portable way to write this command is
kill -9 -$gpid
None of the ways to specify a signal name rather than a signal number work on the Unixes that froze their shell utilities in the mid-90s, which is basically all of them except Linux and the open-source BSDs. However, SIGKILL is reliably signal number 9 and has always been so (since V7 if not earlier).
The special argument -- isn't portable either, and is unnecessary in this case.
If you want to be a little more polite about it (sending SIGTERM instead) then use
kill -15 -$gpid
Again, that number is reliable all the way back to V7.
When bash is invoked as sh (e.g. via symlink, as in your case), it uses a sh compatibility mode where most modern features are turned off. I'd bet sh is calling the external binary for kill, and it doesn't recognize SIGKILL, but the bash invocation is using its builtin, and that builtin does.
It's all about bash compatibility. Quick fix to use /bin/bash because sh can't recognize SIGINT or other features.

ps command output on AIX, HPUX and Solaris

I am writing a portable shell script to get system process information, I need process id, command, pwdx (linux). On linux I am able to get this information as follows.. but it fails on all other unix flavours.
$ ps -awwwwwww -u <userid> -o pid,cmd|grep -i <filter_term> | egrep -v grep
$ pwdx <pid>
what I should use on AIX, HPUX and Solaris to get the similar information, or there any cross platform command
On Solaris I have tried /usr/ucb/ps but that support formatted output and lsof for pwdx equivalent but that also doesn't show what I need
On Solaris I have tried /usr/ucb/ps but that support formatted output:
What is wrong with formatted output ?
and lsof for pwdx equivalent but that also doesn't show what I need.
That doesn't make sense. pwdx is a Solaris native command and was even originally implemented on that OS.
Linux != Unix. And in the same hand, the commands are not always going to be the same, for instance GNU ps is not like Solaris ps or HP-UX ps etc. In some cases the Vendor Unix flavors offer a "compatibility binary" like those stashed in /usr/ucb on solaris. But ultimately you need to look at the man page for each version and review the output format options.
Edit. That is for in general all commands. Including grep, egrep etc.
To show the full command name, use this
ps -eo comm
This will show the command that was run. (ps is from /usr/bin on my Solaris system 5.11)

lsof not giving o/p for bash built in read

When I do
find /
on a terminal and then do on another terminal
lsof -a -d 0-2 -c fin
I see o/p listed from execution of lsof command.
But when I do
echo hi ; read -t 30 hello
hi
on the same terminal ( as find) and do (on different terminal)
lsof -a -d 0-2 -c read
I don't get any output from lsof command
Why ? Is it because read is bash built in ? Whats happening here ?
You got it right. "read" is a shell built-in. The process name remains sh (or bash, or zsh, or whatever else is your shell of choice).
Moreover, though for some shell built-ins there are binary alternatives, there isn't one for read. Really because of its syntax, it takes in the name of a shell variable that gets assigned the result of reading from the stdin. If it was an external program, it could never set the variable in the calling shell.

Resources