No Sockets found: screen script called on startup - linux

I have added a script called screen_tronserver.sh to the /etc/init.d/ directory. I have set the permissions so it is executable and called
update-rc.d /etc/init.d/screen_tronserver.sh defaults 100
to add the script to startup.
Inside the file is the following:
#!/bin/bash
echo "creating screen and starting tron server..."
screen -S tronserver -m /home/pi/programming/tronserver/a.out
The a.out file is a compiled program which runs a server I have created. Now when I call
screen -ls
It says no sockets found. However, I have tried connecting to the server and it is successful, indicating the screen/socket is there somewhere, running in the background.
So why can I not see this mystical socket!?

As Andrew is already alluding to, init scripts are run as root, and screens belong to different users. When you type screen -ls you will see the screens of the current user, not all screens on the system.
So yes, sudo screen -ls or sudo screen -r will do the trick.
Edit (for completeness and future reference): as pointed out by the OP, it is necessary to also add the -d flag to the screen command to detach right away in the init script, or else the screen will remain attached.

Related

bash script to auto run on boot, make screen, execute a command and detach

I am using Centos 7 and on boot I would like to:
Make a screen
Execute a command: osrm-routed --algorithm=MLD
~/osrm-backend/profiles/australia-latest.osrm
Detatch from screen (possibly not needed, just as long as I can
access it myself after its running in future)
Here is something I have thought about, although not correct and wont work
filename: mapstart.sh
Contents of file:
#!/bin/bash
/usr/bin/screen -dmS mapapi osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
With your help with the script. I am not sure the best way to run that on boot with centos 7.
Appreciate your help and input.
For those who would like to know. The issue was with OSRM and centos. I was able to get it running using the full paths of everything and the following in crontab -e
To get the full path of osrm-backend i ran the command of:
which osrm-routed
It returned the result of:
/usr/local/bin/osrm-routed
That then enabled me to add the full path of the command I was trying to run from crontab -e which is required. From there it worked running the below in crontab -e
#reboot /usr/bin/screen -dm -S pistartup /usr/local/bin/osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
break down of all the above:
runs command at reboot only:
#reboot
full path to screen command:
/usr/bin/screen
create screen with name of pistartup and detach:
-dm -S pistartup
my particular command i wanted to run inside the screen:
/usr/local/bin/osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
Now when ever the machine is rebooted. it has created a screen and run my command. To resume the screen manually If i ever wanted to, i could issue the command of:
screen -r pistartup

Background shell script can't reach directories after ssh logout, even with nohup

I want to run a shell script in the background on a server machine and starts that shell script from an ssh connection. Even though I run the background process script with nohup, the background script fails due to an directory unreachable error as soon as I close my ssh connection (and no sooner).
runInBackground.sh:
#!/bin/bash
...
nohup ./run.sh > /dev/null 2> local/errorLog.txt < /dev/null &
run.sh:
#!/bin/bash
...
while [ true ] ; do
...
cd optaplanner-examples
mvn exec:exec // calls java process
cd ..
done
So when I run runInBackground.sh, everything works fine for hours, until I disconnect my ssh connection.
As soon as I log out, the errorlog.txt fills up with:
java.io.FileNotFoundException: /home/myUser/server/optaplanner-simple-benchmark-daemon/local/output/
./run.sh: line 64: /home/myUser/server/optaplanner-simple-benchmark-daemon/local/processed/failed_machineReassignmentBenchmarkConfig.xml: No such file or directory
fatal: Could not change back to '(unreachable)/server/optaplanner-simple-benchmark-daemon/local/optaplannerGitClone/optaplanner': No such file or directory
ls: cannot access /home/myUser/server/optaplanner-simple-benchmark-daemon/local/input: No such file or directory
ls: cannot access /home/myUser/server/optaplanner-simple-benchmark-daemon/local/input: No such file or directory
ls: cannot access /home/myUser/server/optaplanner-simple-benchmark-daemon/local/input: No such file or directory
... // 1000+ more of that ls error
(Full source code)
well, it's not necessarily an encrypted home directory, but likely it's an auto-mounted home directory (e.g over NFS or so). It's mounted upon session startup, and unmounted upon exit. An encrypted home dir is only one of the possible reasons to use such a technique.
The main question is what's the rule that determines whether a user needs home dir or not. I would expect that it could be an allocated pty. You could test if it's actually true by starting a non-interactive SSH session w/o a pseudo-terminal: ssh -T user#host ls /home/myUser/server. I could expect that in this case you won't get a proper directory listing.
Then I would use a program like screen to prolongate interactive session lifetime beyond SSH session limits.
The server might use some other mechanism to provide the home directory for interactive SSH sessions. E.g. monitor interactive sessions listed in utmp In this case you will need a program that would keep the record as long as you need for your service. Perhaps you could use an automatically re-established SSH session. For example I use the following systemd unit to automatically keep a ssh tunnel from one of my workstations in different private networks:
[Unit]
Description=A tunnel to SOME_HOST
PartOf=sshd.service
Requires=network.service
[Service]
ExecStart=/usr/bin/ssh -N -q -R 2222:localhost:22 SOME_HOST
Restart=on-failure
RestartSec=5
User=tunnel
Group=tunnel
[Install]
WantedBy=sshd.service
WantedBy=network.service
When a failure occurs, systemd automatically restarts the unit and SSH session is re-established.
I always use the screen utility to run my scripts instead of nohup.
With screen your process will keep running in even your current ssh session times out or gets disconnected.
Use as follows -
apt-get install screen (On Debian based Systems)
OR
yum install screen (On RedHat based Systems)
To run your application and check the output live (provided your script file does not start a background process and it outputs to the stdout and/or stderr
cd your_app_directory_path
screen ./your_script.sh
Once you are done and want to leave (without stopping the process), use CTRL + A + D to detach the screen.
To check your processes which are run using the screen utility -
screen -r
to reattach a running process
screen -r <screen id or name>
Hope this was useful.
One workaround is to use screen to keep the ssh session open. You can use screen -r to reconnect to the session if you get disconnected.

Executing screen within a script fails when script is launched with PHP

I am using php to execute a script on my server.
PHP: exec("screen -dmS testingscreen /home/username/otherfolder/test.sh")
For a while I was unable to do this till I did some digging and found a few things about how to do this. I also found some items about other things relating to screen / minor issues I was having at the same time.
I will show each issue I had in detail up to the last issue which I can not seem to figure out a fix.
Issue one (Resolved): Trying to run script outside of webroot.
Topic: Excute script outside of web root with PHP.
Solution: Used sudo chown www-data:www-data filename.sh giving my web user access to the script.
Issue two (Resolved): Script does nothing when php file invokes it.
Solution: Make script executable with chmod +x filename.sh
Notes: It was painfully obvious what I did wrong when I used ls in my script dir.
Issue three (Resolved): Unable to su to www-data to check if screens were running.
Error: This account is currently not available.
Problem: www-data was set to /bin/nologin in /etc/passwd
Solution: chsh -s /bin/bash www-data to make it so I can switch to it as user.
Issue four (Resolved): While in su www-data could not use screen -r testingscreen
Error: Cannot open your terminal '/dev/pts/0' - please check.
Problem: Permissions, not opening screen under login account and trying to use su account.
Solution: Using script /dev/null in terminal before trying screen -r testingscreen.
Issue five (Not Resolved):
While executing screen -dmS testingscreen /home/username/anotherfolder/filename.sh
With php's exec() does make screen testingscreen
I have a line in the script file that says
screen -dmS scriptscreen mono '/home/username/otherfolder/myprogram.exe' 'programargs1' 'programargs2' 'args3' 'args4'
This screen fails to run when executed with the script "filename.sh"
However executing this same line as the www-data user (Using sudo su www-data to be that user.) works fine.
Also of note: Running screen -dmS testingscreen /home/username/otherfolder/test.sh works absolutely fine and starts up like it should including scriptscreen. This works while using sudo su www-data but not if I start the script with php.
On the more bizarre side of this, using screen -dmS testingtop top works fine when inside the script file that is started by php. Am I missing something obvious here?
I have checked file permissions and everything is fine, it should work. Being able to run my program as www-data means that the perms are set up fine. It just seems like it's something to do with php or my server in general. Any help or possible tips are very welcome and I hope my detailed issue+solution write up may help others in the future all in one post.
Since you are envoking sudo as part of your question i assume this is an attempt at getting PHP to execute a script with root permissions?
I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
//if I misunderstood your question and the script does not require
//root permissions you can change the
//second argument on getShell() to false. That will return a bash shell
//with permissions from www-data.
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('/home/username/otherfolder/test.sh');

Run commands in screen after creating one per bash

I have the following bash file which should create a screen, go to a directory and then start a node script:
screen -S shared // 1
cd /home/nodejsapp // 2
node start.js app.js // 3
The problem is, after executing 1, I indeed see the screen 'shared', but 2 & 3 will execute on the previous terminal, not on the screen 'shared'.
How can I achieve that commands 2 and 3 will be executed on the current screen?
You may create a detached screen and then send commands to it. For example:
screen -d -m -S shared
screen -S shared -X -p 0 stuff $'cd /home/nodejsapp\n'
screen -S shared -X -p 0 stuff $'node start.js app.js\n'
If you need to attach to the screen session afterwards, then you can add one more line:
screen -S shared -r
See screen's manual for more details:
screen options
screen commands
You could run a "server" as the program within screen, which reads commands to execute from the pseudoterminal which the "tty" program identifies. For instance, as I'm writing this, tty says (inside screen)
/dev/pts/2
and I can write to it by
date >/dev/pts/2
On the server side, the script would read line-by-line in a loop from the same device. (On some other systems, there are differently-named
devices for each side of the pseudoterminal).
That only needs a script which starts by getting the output of "tty", writing that to a file (which a corresponding client would know of), and then the client would read commands (whether from the keyboard or a file), write them to the server via the pty device.
That's doable with just a couple of shell scripts (a little more lengthy though than the usual answer here).

Run script with rc.local: script works, but not at boot

I have a node.js script which need to start at boot and run under the www-data user. During development I always started the script with:
su www-data -c 'node /var/www/php-jobs/manager.js
I saw exactly what happened, the manager.js works now great. Searching SO I found I had to place this in my /etc/rc.local. Also, I learned to point the output to a log file and to append the 2>&1 to "redirect stderr to stdout" and it should be a daemon so the last character is a &.
Finally, my /etc/rc.local looks like this:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
su www-data -c 'node /var/www/php-jobs/manager.js >> /var/log/php-jobs.log 2>&1 &'
exit 0
If I run this myself (sudo /etc/rc.local): yes, it works! However, if I perform a reboot no node process is running, the /var/log/php-jobs.log does not exist and thus, the manager.js does not work. What is happening?
In this example of a rc.local script I use io redirection at the very first line of execution to my own log file:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exec 1>/tmp/rc.local.log 2>&1 # send stdout and stderr from rc.local to a log file
set -x # tell sh to display commands before execution
/opt/stuff/somefancy.error.script.sh
exit 0
On some linux's (Centos & RH, e.g.), /etc/rc.local is initially just a symbolic link to /etc/rc.d/rc.local. On those systems, if the symbolic link is broken, and /etc/rc.local is a separate file, then changes to /etc/rc.local won't get seen at bootup -- the boot process will run the version in /etc/rc.d. (They'll work if one runs /etc/rc.local manually, but won't be run at bootup.)
Sounds like on dimadima's system, they are separate files, but /etc/rc.d/rc.local calls /etc/rc.local
The symbolic link from /etc/rc.local to the 'real' one in /etc/rc.d can get lost if one moves rc.local to a backup directory and copies it back or creates it from scratch, not realizing the original one in /etc was just a symbolic link.
I ended up with upstart, which works fine.
In Ubuntu I noticed there are 2 files. The real one is /etc/init.d/rc.local; it seems the other /etc/rc.local is bogus?
Once I modified the correct one (/etc/init.d/rc.local) it did execute just as expected.
You might also have made it work by specifying the full path to node. Furthermore, when you want to run a shell command as a daemon you should close stdin by adding 1<&- before the &.
I had the same problem (on CentOS 7) and I fixed it by giving execute permissions to /etc/local:
chmod +x /etc/rc.local
if you are using linux on cloud, then usually you don't have chance to touch the real hardware using your hands. so you don't see the configuration interface when booting for the first time, and of course cannot configure it. As a result, the firstboot service will always be in the way to rc.local. The solution is to disable firstboot by doing:
sudo chkconfig firstboot off
if you are not sure why your rc.local does not run, you can always check from /etc/rc.d/rc file because this file will always run and call other subsystems (e.g. rc.local).
I got my script to work by editing /etc/rc.local then issuing the following 3 commands.
sudo mv /filename /etc/init.d/
sudo chmod +x /etc/init.d/filename
sudo update-rc.d filename defaults
Now the script works at boot.
I am using CentOS 7.
$ cd /etc/profile.d
$ vim yourstuffs.sh
Type the following into the yourstuffs.sh script.
type whatever you want here to execute
export LD_LIBRARY_PATH=/usr/local/cuda-7.0/lib64:$LD_LIBRARY_PATH
Save and reboot the OS.
I have used rc.local in the past. But I have learned from my experience that the most reliable way to run your script at the system boot time is is to use #reboot command in crontab. For example:
#reboot path_to_the_start_up_script.sh
This is most probably caused by a missing or incomplete PATH environment variable.
If you provide full absolute paths to your executables (su and node) it will work.
It is my understanding that if you place your script in a certain RUN Level, you should use ln -s to link the script to the level you want it to work in.
first make the script executable using
sudo chmod 755 /path/of/the/file.sh
now add the script in the rc.local
sh /path/of/the/file.sh
before exit 0
in the rc.local,
next make the rc.local to executable with
sudo chmod 755 /etc/rc.local
next to initialize the rc.local use
sudo /etc/init.d/rc.local start
this will initiate the rc.local
now reboot the system.
Done..
I found that because I was using a network-oriented command in my rc.local, sometimes it would fail. I fixed this by putting sleep 3 at the top of my script. I don't know why but it seems when the script is run the network interfaces aren't properly configured or something, and this just allows some time for the DHCP server or something. I don't fully understand but I suppose you could give it a try.
I had exactly same issue, the script was running fine locally but when I reboot/power-on it was not.
I resolved the issue by changing the file path. Basically need to give the complete path in the script. While running locally, file can be accessed but when running on reboot, local path will not be understood.
1 Do not recommend using root to run the apps such as node app.
Well you can do it but may catch more exceptions.
2 The rc.local normally runs as root user.
So if the your script should runs as another user such as www U should make sure the PATH and other environment is ok.
3 I find a easy way to run a service as a user:
sudo -u www -i /the/path/of/your/script
Please prefer the sudo manual~
-i [command]
The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a loginshell...
rc.local only runs on startup. If you reboot and want the script to execute, it needs to go into the rc.0 file starting with the K99 prefix.

Resources