4

I have a script that is suppose to stop and recover the process to run in the background:

process_id=`ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
(kill -STOP $process_id) &
... # do something else 
(kill -CONT $process_id) &

This is working fine, but then in the STDOUT / STDERR this appears:

[1]  +  8545 Suspended (signal)            /etc/init.d/...

So far I tried to:

(kill -STOP $process_id)

(kill -STOP $process_id) & > /dev/null

/etc/init.d/{name_of_the_daemon} start > /dev/null

(kill -STOP $process_id & ) 2>/dev/null 

(kill -STOP $process_id & disown;) 2>/dev/null 

set +m
(kill -STOP $process_id) & 

(kill -STOP $process_id) & 1>&2

These are the steps that I'm doing:

  1. create a file fff in /etc/init.d/
  2. paste the script from below
  3. chmod 755 fff
  4. /etc/init.d/fff start

After that, I receive the "suspended" message...

According to @sourcejedi my script is not a daemon; when a child process of the script has been suspended, the "suspended" message appears

How can I suppress the output from the shell for only that particular message?

Here is a very simple version of my script:

#!/bin/bash

pid_script=`ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`

case "$1" in
    start)
    ( sleep 3; kill -STOP $pid_script ) &
    sleep 10;
    (sleep 1; kill -CONT $pid_script) &
    ;;
    stop)
    for p in $pid_script # kill all the other processes related with this script (if any)
        do
            kill -9 $p
        done
esac
sourcejedi
  • 50,249
toom501
  • 205
  • 1
    I doubt that this appears on standard output. Why are you running the kill in the background? What is $process_id? How did you start the process that $process_id is the PID of? – Kusalananda Sep 18 '18 at 07:33
  • Hi and welcome to UL.se! I think you came to the right place with your question, however, we need to know a little bit more about what you are trying to do. Why are you forking the kill statement? It really shouldn't take that long... Also, what have you tried so far? Have you even tried redirecting STDOUT or even STDERR? If so, why do you think it didn't work for you? Which Shell are you using? – Bananguin Sep 18 '18 at 07:39
  • I'm running the kill in the background because I though that it could be hide the "Suspended" string; I edited the question with the definition of the $process_id: process id is the ID of my running process, which contains those lines of bash script. – toom501 Sep 18 '18 at 07:56
  • The goal that I want to achieve is: the daemon should start another process which must run in the background but also it require some credential when you call it. Thus I created the lines that you see in the question to override my problem: suspend my daemon, start the other process, recover the daemon and put it in the background – toom501 Sep 18 '18 at 08:03
  • So far I tried to: not to put the kill in the background and also to redirect the stdout in the /dev/null like this: (kill -STOP $process_id) & > /dev/null. I've no idea why is not working... FYI I'm using a bash shell – toom501 Sep 18 '18 at 08:05
  • 4
    The suspended message is not issued by the kill command. You can see it if you open two terminal windows. In the first window you type sleep 999 &, and in the second window you do a kill -STOP ... for the PID of the sleep command. You will see that the suspended message occurs in the first window, not in the one where the kill is executed. – user1934428 Sep 18 '18 at 08:15
  • Ah ok, I get it @user1934428 :) that's something that I didn't know before.... So what should I do? – toom501 Sep 18 '18 at 08:17
  • @toom501 : I would follow the first of the links Fólkvangr posted, and in particular his own elaborate explanation on that page. – user1934428 Sep 18 '18 at 12:32
  • @Fólkvangr I followed some of the things that was proposed in the other questions, but nothing... as you can see I edited my question with the other attempts – toom501 Sep 18 '18 at 15:05
  • @Fólkvangr oh really? hmm ok... I'll try something else but if you want you can put your previous comment as an answer and I'll choose it since for now there's no valid answer for the question... – toom501 Sep 18 '18 at 17:01
  • 1
    @Fólkvangr the daemon and my daemon script are different; to run the daemon in the background I just call it inside my daemon script and then I put my entire daemon script in the background; yes, the daemon is my background process, is a java jar file. I hope this will help... – toom501 Sep 19 '18 at 07:43
  • 1
    @Fólkvangr I added a very simple version of my daemon script (fff is the name of it); in my normal daemon, in the line with sleep 10 the process to run in the background – toom501 Sep 19 '18 at 11:19
  • Note also that although a bash example is given, the wording and formatting of the "[1] + 8545 Suspended (signal)" message is that of csh not that of bash. – mr.spuratic Sep 20 '18 at 11:02

2 Answers2

2

When you see [1] + 7766 Suspended (signal) ..., this is a message printed by the shell, telling you that one of its child processes has been suspended.

In the fff example, there are two shell processes to consider. Your initial interactive shell, and the shell script which runs as a child process.

Your script arranges to suspend itself. The "Suspended" message is printed by the interactive shell. So this is not an option that you can toggle on or off inside the script.

Additionally, there is no option you could set in the interactive shell to toggle this specific message on or off. It is not possible to "suppress" this message individually... basically because this is never what you want to do :-).

I think the fff script does not successfully resume itself anyway. I think it might be possible to modify it to do so. However, resuming itself is a terrible idea. When you suspend the script, the interactive shell shows its command prompt again. I.e. if you didn't see the "suspended" message, it looks like your script has finished. But either way, if your script managed to resume itself, it would try to steal back control of the terminal from the user, no matter what they had started to do in the mean time. This is not good!


I think you need to understand e.g. that if you launched a process from your terminal and it is a child process of your interactive shell, then it is absolutely not a daemon process.

To start a daemon from your terminal, the program must fork() itself during startup. The original process should exit, and this allows the process which continues to be re-parented e.g. (in traditional unix) to PID 1 a.k.a. the init process. And there are more steps it must include as well, to detach from the terminal. See for example here: Daemonize a process in shell?

Additionally if your system uses systemd, you need to understand that legacy /etc/init.d/ scripts are required to be started using systemctl start. The packaged init.d scripts in Debian and elsewhere include a compatibility hack that does this for you. But you should not use that feature. It is a recipe for confusion. The script you have writen does not have this feature, so you must use systemctl start fff.

I strongly recommend not trying to use the games in the fff script in combination with systemctl start.

In reality systemctl uses a different approach to start background service processes. It sends a message to PID 1 (the systemd init process), and PID 1 starts the requested program. If you define a native systemd service, the program does not need to daemonize itself. If you use a legacy init.d script, the program still needs to daemonize itself, but the only thing it achieves is to tell systemd that the init.d script has finished starting. (This makes it possible to notice some startup failures in daemons, though unfortunately many existing programs have startup failures that can happen after the daemonization step).

You do not want to be worrying about whether and how systemd will react to the init.d script stopping and resuming itself.

sourcejedi
  • 50,249
  • Maybe I didn't understand what you're doing but can you post a new version of my simple version of the daemon thus I can test it properly? – toom501 Sep 19 '18 at 12:43
  • I tried but the [1] + 7766 Suspended (signal) remains... – toom501 Sep 19 '18 at 13:06
  • Ok, so as you said, my script is not a daemon but it has some child processes that has been suspended; how can I suppress the output from the shell for that particular message? – toom501 Sep 20 '18 at 07:22
  • 1
    I edited my question. – toom501 Sep 20 '18 at 08:27
  • As I mentioned in the question, the fff is a very simple version of my script; I need to go back to the script; so you say is not possible to suppress that message from the shell... seems like you're right... – toom501 Sep 20 '18 at 09:58
  • @Fólkvangr toom501 hasn't told me what init system their system uses. But, they are installing a script as /etc/init.d/fff. My point is that if they were using one of the popular Linux distributions, the steps that they showed to reproduce this, are not steps that you actually want to be doing. There seems a big risk of learning a pattern and later finding it does not apply to the general case you wanted it to. – sourcejedi Sep 20 '18 at 10:29
  • I spoke with my supervisor and I will use some different approach for this task... thanks to all of you for trying to help me :) I'll accpet this as the answer because you said: "It is not possible to "suppress" this particular message..." – toom501 Sep 20 '18 at 11:47
  • 1
    @toom501 ta :-). So I shifted it towards the top. It's tricky to phrase that answer accurately, because there are other theoretical cases where you can suppress exactly this message, as per the first version of this answer in the revision history :-). And I think you want to know whether what you're hitting is "just" an oversight that could be filled (i.e. you could hypothetically send a patch to add it to bash :-), or if there's a deeper problem with what you're doing...(I hope I wasn't doing too much of a derail or nitpicking the discussion after you'd decided to take a different approch) – sourcejedi Sep 20 '18 at 12:30
  • no no, don't worry! The different approach will be to add two more parameter when you initialise the script; nothing more than that :) – toom501 Sep 20 '18 at 12:57
0

Unsure if I understand your goal properly, but this is how it works for me:

  1. start "daemon", in fact just continuouslu running process: top -d1 >out

  2. in the second terminal you can tail -f out if you like

  3. in the third terminal I run kill -STOP $(ps -eFH | grep "top -d" |grep -v grep|awk '{print $2}'

You will see the 'suspended' message in the first terminal where the daemon was started from, but in the out file there won't be such messages.

Putnik
  • 886
  • 1
    The problem is that i run the daemon and the kill in the same terminal because they are in the same script; hence the "suspended" message will still appears – toom501 Sep 19 '18 at 07:39
  • what if you close the terminal where the daemon was started from? what's wrong there, isn't it a daemon? – Putnik Sep 20 '18 at 17:37