script not running before sleep - bash

I am trying to create a script that runs just before sleeping. Can someone tell me what I am doing wrong here? This script runs perfectly when I run the command in terminal.
king#death-star /etc/pm/sleep.d $ ls
total 1MB
drwxr-xr-x 2 root root 1MB May 30 15:21 .
drwxr-xr-x 5 root root 1MB Nov 28 2015 ..
-rwxr-xr-x 1 root root 1MB Jun 26 2015 10_grub-common
-rwxr-xr-x 1 root root 1MB Dec 6 2013 10_unattended-upgrades-hibernate
-rwxr-xr-x 1 root root 1MB May 22 2012 novatel_3g_suspend
-rwxr-xr-x 1 root root 1MB May 30 15:20 revert_kb_on_sleep
king#death-star /etc/pm/sleep.d $ cat revert_kb_on_sleep
sh -c "/home/king/Desktop/Scripts/rotate_desktop normal; /home/king/Desktop/Scripts/misc/my_keyboard on"
Output from log:
$ cat /var/log/pm-suspend.log
Running hook /etc/pm/sleep.d/revert_kb_on_sleep suspend suspend:
Can't open display
Can't open display
xrandr: --rotate requires an argument
Try 'xrandr --help' for more information.
No protocol specified
Unable to connect to X server
/etc/pm/sleep.d/revert_kb_on_sleep suspend suspend: success.
Mon May 30 15:23:39 EDT 2016: performing suspend
Mon May 30 15:27:59 EDT 2016: Awake.
Mon May 30 15:27:59 EDT 2016: Running hooks for resume
Running hook /etc/pm/sleep.d/revert_kb_on_sleep resume suspend:
Can't open display
Can't open display
xrandr: --rotate requires an argument
Try 'xrandr --help' for more information.
No protocol specified
Unable to connect to X server
/etc/pm/sleep.d/revert_kb_on_sleep resume suspend: Returned exit code 1.

Any luck with this? I wrote a script to run after waking, and I'm getting similar errors. This script is supposed to turn off the laptop display upon waking from sleep.
case "${1}" in
resume|thaw)
screen_status=$(xset -q -display :0.0 | tail -1 | sed 's/^[ \t]*//g')
if [[ "$screen_status" = "Monitor is On" ]]; then
sleep 1 && xset -display :0.0 dpms force off
fi
;;
esac
But I get the following error:
No protocol specified
xset: unable to open display ":0.0"
I've tried to get it to set screen_status as "Monitor is off" when it can't get a display, so that it triggers the condition to execute xset anyway, but that's not working, either, because it can't access the display. In the meantime, I set xfce4-power-manager to turn off the screen after 1 minute. Having to wait for a minute is better than nothing!

Related

Bash: Running a script that runs another script as a separate process

I have a script that does stuff with an ID as a parameter, I want to make it accept multiple parameters and then duplicate itself so that each copy runs with its own parameter from the list. For instance, I run "script 1 2 3&", and I want to see the result as if I were to run "script 1&", "script 2&", and "script 3&".
I can launch a script inside a script using
MyName="${0##*/}"
bash ./$MyName $id
$id is basically the parameter I want to put in this script. I launch multiple of them; however, the scripts I launch from within the script get processed in a raw, one after another, not parallel. I tried adding '$' at the end after $id, did not work.
Is it possible to launch a script from a script so that they run as separate processes in the background as if I were to run multiple scripts with & myself from the terminal?
This does what I think you want... with some dummy example code for the case of handling a single id.
If no parameters are given, it will give you Usage: output, if more than one parameter is given it will invoke itself as a background job, once for each of those parameters, and then wait for those background jobs to be finished.
If only one parameter is given, it will execute the workload for you.
A cleaner approach would probably be to do this in two scripts, one that is the launcher that handles the first two situations, and a second script that handles the work load.
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage $0 <id1> ..." 1>&2
exit 1
fi
if [ $# -gt 1 ]; then
# Fire up the background jobs
for myid in $*; do
$0 $myid &
done
# Now wait for the background scripts to finish
wait
exit 0
fi
id=$1
echo "PID $$ ($id) - Hello world, on $(date)."
sleep 5
Example run:
$ ./myscript.sh 10 20 30 40 50; date
PID 8558 (10) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8559 (20) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8560 (30) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8561 (40) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
PID 8563 (50) - Hello world, on Tue Jun 21 22:22:10 PDT 2022.
Tue Jun 21 22:22:15 PDT 2022
The ; date at the end shows that the initial script doesn't return until all child processes are finished.

Unexpected output from redirection

I'm encountering a strange problem when redirecting STDOUT and STDERR. The following works as expected:
$ gvim --version > /tmp/version.out
$ ls -l /tmp/version.out
-rw-r--r--. 1 blah blah 3419 Jun 27 17:28 /tmp/version.out
There are 3419 characters in the output file and when I look at the file, it contains what I expect.
However, it does not work as expected when I do the following:
$ gvim --version > /tmp/version.out 2> /tmp/version.err
$ ls -latr /tmp/version.*
-rw-r--r--. 1 blah blah 0 Jun 27 17:29 /tmp/version.out
-rw-r--r--. 1 blah blah 0 Jun 27 17:29 /tmp/version.err
Notice that both the .out and the .err files are zero length this time. I tried this with an ls command and it works as expected:
$ ls . /ZZZ > /tmp/ls.out 2> /tmp/ls.err
$ ls -l /tmp/ls.*
-rw-r--r--. 1 blah blah 50 Jun 27 17:45 /tmp/ls.err
-rw-r--r--. 1 blah blah 33 Jun 27 17:45 /tmp/ls.out
Here, the STDERR gets redirected properly:
$ cat /tmp/ls.err
ls: cannot access /ZZZ: No such file or directory
I did an strace on gvim --version and confirmed that it's trying to write the version info to STDOUT (fd 1). It shouldn't matter either way though since I'm trying to capture both STDOUT and STDERR.
What's going on here?
Congratulations, you just found a bug in gvim!
Correct procedure is to file a new issue on GitHub.
You should first try another variations of the bug, so that developers have the debugging easier.
For example, redirecting only STDERR also causes the error, because there was no output written. Also there was returned success (0), which is obviously an bug.
$ gvim --version 2> /tmp/version.err
$ echo $?
0
By only looking into the code one may search for the bug somewhere in version printing, or anywhere in generic --version argument processing, not being done by gtk.
To answer your question
What is going on?
It's a program error, made by developers of gvim and I would not recommend you to put effort into finding its root cause unless you are experienced with coding vim or if you want to learn, how vim works. In that case, your best shot is to fork the repo and after fixing it, submitting a pull request, so that everyone can benefit from your work.
The specific condition that triggers the bug seems to be when standard error is not a terminal. When I tried redirecting standard error to another terminal device, the --version message was still printed to standard output.
ek#Io:~$ gvim --version 2>/dev/null
ek#Io:~$ tty
/dev/pts/1
ek#Io:~$ who
ek tty7 2017-07-05 02:48 (:0)
ek pts/1 2017-07-10 09:10 (192.168.10.3)
ek pts/3 2017-07-10 09:23 (192.168.10.3)
ek#Io:~$ gvim --version 2>/dev/pts/3
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 24 2016 16:44:48)
....
Apparently Vim calls isatty(2) to help figure out if it should use a terminal at all. From a comment in gui.c:
Return TRUE if still starting up and there is no place to enter text.
For GTK and X11 we check if stderr is not a tty, which means we were (probably) started from the desktop. Also check stdin, "vim >& file"
does allow typing on stdin.
But the rest of that comment (i.e., the part I didn't highlight), and instances of isatty(2) throughout multiple files, make it not immediately obvious what ought to be changed.
Running grep -RF 'isatty(2)' on the source tree revealed that this is used in gui.c, message.c, and main.c. (That doesn't mean the bug is in all those files, of course.) You might also look at all the instances of isatty in the source code.
In any case, as jirislav says, this ought to be reported as a bug--even if a full explanation of the problem is not yet apparent. I am able to reproduce this with the current upstream sources (commit 163095f).

Subshells, permissions and following symlinks on OS X/Darwin: why do I get permission errors?

(Edit: There was a typo that caused the problem. Please see comments on existing answers)
I wanted to stat a file that symlinked to another file and thought that I could use subshells and readlink command substitution to do the job. For context, let me mention that this is on OS X 10.8.3 (Darwin).
But I ran into a permission denied error.
ujagtahb#ujags-Retina-MBP-5.local:~/Code_Pen/c_exp$(cd /usr/share/locale/; stat $(en_US/LC_COLLATE))
bash: en_US/LC_COLLATE: Permission denied
727393128 1449 crw--w---- 1 ujagtahb tty 268435496 0 "Aug 12 11:36:50 2013" "Aug 12 11:36:51 2013" "Aug 12 11:36:51 2013" "Aug 12 11:36:51 2013" 131072 0 0 (stdin)
I checked the output of the readlink command and sure enough, I didn't see anything wrong with it.
ujagtahb#ujags-Retina-MBP-5.local:~/Code_Pen/c_exp$readlink /usr/share/locale/en_US/LC_COLLATE
../la_LN.US-ASCII/LC_COLLATE
stating the file directly raised no error and produced the output I needed.
ujagtahb#ujags-Retina-MBP-5.local:~/Code_Pen/c_exp$stat /usr/share/locale/la_LN.US-ASCII/LC_COLLATE
16777218 284538 -r--r--r-- 1 root wheel 0 2086 "Aug 12 11:36:51 2013" "Jul 22 07:55:02 2012" "Jul 22 07:55:02 2012" "Jun 21 01:35:25 2012" 4096 0 0x20 /usr/share/locale/la_LN.US-ASCII/LC_COLLATE
What's causing the permission denied in one case but not the other?
This:
(cd /usr/share/locale/; stat $(en_US/LC_COLLATE))
means "open a subshell, cd to /usr/share/locale, run the command en_US/LC_COLLATE, and run stat on the output".
But I think the command you want to run is readlink en_US/LC_COLLATE, not en_US/LC_COLLATE; so:
(cd /usr/share/locale/; stat $(readlink en_US/LC_COLLATE))
(I'm guessing this was just a typo?)
$(en_US/LC_COLLATE)
will execute string en_US/LC_COLLATE as command (script).
Since it does not have execute permission shell will output that error.
Probably you wanted to do it that way:
$(cd /usr/share/locale/; stat en_US/LC_COLLATE)

Not execution of shell script with nohup

I have a problem executing a shell script with the "modifier" nohup.
The script executed without nohup works fine.
The script have all the rights. And the error message is really weird.
oracle#serveur6:/home/oracle/xxx/yyy/test>ls -ltr
total 16
-rwxrwxrwx 1 oracle dba 1620 Jun 7 14:56 lanceur2.sql
-rwxrwxrwx 1 oracle dba 48 Jun 7 14:56 alt_script.ksh
drwxrwxrwx 2 oracle dba 256 Jun 7 14:57 log
oracle#serveur6:/home/oracle/xxx/yyy/test> nohup /home/oracle/admin/ESPACE/test/alt_script.ksh &
[1] 25493628
oracle#clay925p6:/home/oracle/admin/ESPACE/test> Sending output to nohup.out
nohup: /home/oracle/admin/ESPACE/test/alt_script.ksh: **No such file or directory**
[1] + Done(127) nohup /home/oracle/admin/ESPACE/test/alt_script.ksh &
Things to check:
The path to the script is correct.
The script has executable permission set.
the first line of the script contains something like #!/bin/sh
nohup runs a command in the background, thus the script must be executable like any other command.

How does Erlang heart work?

This question is related to my previous one: Running erlang shell as a daemon/service
I have a script that looks like this:
#!/bin/bash
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
export HEART_COMMAND="/etc/init.d/script restart"
start() {
erl -heart -pa DIR -sname NAME -setcookie COOKIE -env port 21 -s M -s M2 --
### Create the lock file ###
touch /var/lock/lock
}
stop() {
erl -noshell -sname temp_control -setcookie COOKIE -eval "rpc:call(NAME#ubuntu, init, stop, [])" -s init stop
### Now, delete the lock file ###
rm -f /var/lock/lock
}
### main logic ###
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
# start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
I don't know how to simulate a crash so I just tried ctrl+c and aborted the shell, the output looks like this:
root#ubuntu:/etc/init.d# ./script start
heart_beat_kill_pid = 17512
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.4 (abort with ^G)
(NAME#ubuntu)1> Starting M2
Listening on port 21
(NAME#ubuntu)1>
(NAME#ubuntu)1>
(NAME#ubuntu)1>
(NAME#ubuntu)1>
(NAME#ubuntu)1>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
heart: Fri Jul 29 09:25:10 2011: Erlang has closed.
root#ubuntu:/etc/init.d# heart_beat_kill_pid = 17557
heart: Fri Jul 29 09:25:13 2011: Erlang has closed.
/etc/init.d/NAME: line 20: 17557 Killed erl -heart -pa DIR -sname NAME -setcookie COOKIE -env port 21 -s M -s M2 --
heart: Fri Jul 29 09:25:13 2011: Executed "/etc/init.d/script restart". Terminating.
heart_beat_kill_pid = 17602
heart: Fri Jul 29 09:25:15 2011: Erlang has closed.
/etc/init.d/NAME: line 20: 17602 Killed erl -heart -pa DIR -sname NAME -setcookie COOKIE -env port 21 -s M -s M2 --
heart: Fri Jul 29 09:25:15 2011: Executed "/etc/init.d/script restart". Terminating.
heart: Fri Jul 29 09:25:17 2011: Executed "/etc/init.d/script restart". Terminating.
root#ubuntu:/etc/init.d#
This goes on for ever if I don't comment the line of code in the script that starts it. It's like an endless loop of terminating erlang shells... or something.
If I try for example "export HEART_COMMAND="/bin/echo hello" it says "write error: broken pipe".
Why doesn't it work? How do I simulate a crash properly to check if the heart command work?
Thankful for any advice you might have.
Answering the question you didn't ask
(but mentioned a couple of times that you don't know how to do)
To simulate a crash so kill -SEGV <PID>
Example:
$ sleep 30 &
[1] 13274
$ kill -SEGV 13274
[1]+ Segmentation fault sleep 30
Also, So while I don't know erlang, I presume that it spawns multiple threads and one thread can monitor another by sending heartbeat messages. If the other thread does not respond, it is assumed to be hung and restarted.

Resources