1

I came across this shell script

bash# while true; do
  vmtouch -m 10000000000 -l *head* & sleep 10m
  kill %vmtouch
done

and wonder how does the kill %vmtouch portion work?

I normally pass a pid to kill a process but how does %vmtouch resolve to a pid?

I tried to run portions of script seperately but I got -bash: kill: %vmtouch: no such job error.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
TLJ
  • 4,525
  • 2
  • 31
  • 46
  • 1
    Different things depending on context; `${var%suffixpat}`, f/e, is something different. A title that identifies that context would be better; at first glance with the original title, one might expect this to be one of the many duplicates of [percent symbol in bash: What's it used for?](https://stackoverflow.com/questions/34951901/percent-symbol-in-bash-whats-it-used-for) – Charles Duffy Mar 29 '19 at 16:56

2 Answers2

3

%something is not a general shell script feature, but syntax used by the kill, fg and bg builtin commands to identify jobs. It searches the list of the shell's active jobs for the given string, and then signals that.

Here's man bash searching for /jobspec:

The character % introduces a job specification (jobspec). Job number n may be referred to as %n. A job may also be referred to using a prefix of the name used to start it, or using a substring that appears in its command line. [...]

So if you do:

sleep 30 &
cat & 

You can use things like %sleep or %sl to conveniently refer to the last one without having to find or remember its pid or job number.

that other guy
  • 116,971
  • 11
  • 170
  • 194
2

You should look at the Job control section of the man bash page. The character % introduces a job specification (jobspec). Ideally when you have started this background job, you should have seen an entry in the terminal

[1] 25647

where 25647 is some random number I used. The line above means that the process id of the last backgrounded job (on a pipeline, the process id of the last process) is using job number as 1.

The way you are using the job spec is wrong in your case as it does not take process name of the background job. The last backgrounded is referred to as %1, so ideally your kill command should have been written as below, which is the same as writing kill 25647

vmtouch -m 10000000000 -l *head* & sleep 10m
kill %1 

But that said, instead of relying the jobspec ids, you can access the process id of the background job which is stored in a special shell variable $! which you can use as

vmtouch -m whatever -l *head* & vmtouch_pid=$!
sleep 10m
kill "$vmtouch_pid"

See Job Control Basics from the GNU bash man page.

Inian
  • 80,270
  • 14
  • 142
  • 161