How to create a script that runs gnu screen with multiple windows, each window runs a command
For example
window 1 runs python3 -m http.server
window 2 runs webpack --watch
a screen with 2 windows start when I run script ./start.sh
I figured it out myselft, make a .screenrc file like this
startup_message off
caption always "%{= kw} %-w%{= gW} %n %t %{-}%+w %-="
screen -t http ./scripts/serve.sh
screen -t watch ./scripts/watch.sh
then run screen -c .screenrc
Related
I'm using Linux (Mint 20.3) to run a simple Minecraft server and I want to be able to start the server with a keyboard or desktop shortcut. I also want to be able to interact with the server in a terminal after it starts. I'm currently using the server software supplied by Mojang. I wrote a little program to get things started:
#!/bin/bash
cd /home/trevor/Minecraft_Server
LD_LIBRARY_PATH=. ./bedrock_server
exec $SHELL
I can get the server to run but I have no clue how to get it to open a terminal window so I can interact with the server. I'm relatively new to Linux so any input would be greatly appreciated.
you can use screen to detach and attach to run commands into the minecraft terminal.
to install screen:
apt-get install -y screen
To launch, update your script with something like:
screen -S mcs ./bedrock_server
to reattach, run the following in a terminal:
screen -r mcs
Use screen in your script to reattach to bedrock process.
Install screen:
apt-get install screen
Define your script as:
#!/bin/bash
export LD_LIBRARY_PATH=.
cd /home/trevor/Minecraft_Server
screen -d -m -S bedrock ./bedrock_server
After invoke your script, screen creates a socket that can be used to reattach to your script terminal. You can show screen sockets available with:
screen -ls
Parameter -S defined 'bedrock' as the socket name. So you can open another terminal as you like and reattach to the bedrock process with:
screen -r bedrock
If you detach the screen with CTRL+C the screen will be closed and so the minecraft bedrock server. To deattach without close the process you must use CTRL+A and CTRL+D.
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).
I'm writing a Linux shell script in which I need to start a new screen session, run a node.js server in the screen, then detach from the screen so that my server runs in the background.
Right now, these are the commands I run manually to do this:
screen
node server.js
[detach screen]
However, I need a way to automate this via the script, and if I just use the above commands in a shell script, it creates the screen and gets stuck there. How can I pass the "node server.js" command to the screen command?
EDIT:
Based on the suggested answer I have a script that works, except that I need to manually create a screen and detach from it before I run it. I tried adding screen -d -m as the first line to create a detached screen, but the script hangs after that line.
tempfile=$(mktemp)
indices=`tail -1 debug.log`
cat > $tempfile <<EOF
node server $indices
EOF
screen -X readbuf $tempfile
screen -X paste .
rm -f $tempfile
How can I create and detach a screen with the script?
This didn't work either:
screen
screen -d
It is as simple as this:
screen -md node server.js
This requires the command to run as a service (as it does), otherwise the screen stops immediately.
To optionally also set a name for the session (e.g. "session-name"):
screen -mdS session-name node server.js
You can then attach to the screen with:
screen -rd session-name
If you want to redirect all output to a file, you can do like this:
screen -mdS session-name bash -c 'node server.js &> output.log'
You can then monitor the output with e.g.:
tail -f output.log
You can list your running screens with:
screen -ls
or
screen -list
Example: Start a Python3 web server in a detached screen
Start a Python3 web server listening on port 8000 that serves files in the current directory, in a named
detached screen:
screen -mdS my-web-server python3 -mhttp.server
Or, with logging to a file:
screen -mdS my-web-server bash -c 'python3 -mhttp.server &> output.log'
For Python 2.x it looks like this:
screen -mdS my-web-server bash -c 'python -mSimpleHTTPServer &> output.log'
EDIT: Try this:
tempfile=$(mktemp)
cat > $tempfile <<EOF
node server.js
EOF
screen -S SessionName -X readbuf $tempfile; screen -RdS SessionName
screen -X paste .
rm -f $tempfile
It should create the temp file, create a screen called SessionName and runs the commands, then delete the temp file. Let me know if that works.
I am trying to set up a Minecraft server. However, the basic startup scripts provided do not fit my needs. I want a script that will:
Start a new screen running the jarfile and (pretty much) only the jarfile (so i can ^C it if needed without killing other things like screen or my gzip commands)
Gzip any logs that weren't gzipped automatically by the jarfile (for if/when i ^C'ed the server, or if it crashed)
Run a command with sudo to set the process in the first argument to a high priority (/usr/bin/oom-priority)
Run a http-server on the resource-pack directory in a different screen and send ^C to it when the server closes
I have these three commands. I run startserver to start the server.
startserver:
#!/bin/bash
set -m
cd /home/minecraftuser/server/
echo
screen -dm -S http-server http-server ./resource-pack
screen -dm -S my-mc-server startserver_command
(sleep 1; startserver_after) &
screen -S my-mc-server
startserver_command:
#!/bin/bash
set -m
cd /home/minecraftuser/server/
echo
java -Xmx768M -Xms768M -jar ./craftbukkit.jar $# &
env MC_PID=$! > /dev/null
(sleep 0.5; sudo /usr/bin/oom-priority $MC_PID) &
fg 1
echo
read -n 1 -p 'Press any key to continue...'
and startserver_after:
#!/bin/bash
cd /home/minecraftuser/server/
wait $MC_PID
find /home/minecraftuser/server/logs -type f -name "*.log" -print | while read file; do gzip $file &
done
screen -S http-server -p 0 -X stuff \^c\\r
Edit: When I run startserver, I get a command prompt then a bunch of gzip errors of files already existing (I am expecting these errors, but when I run startserver I'm supposed to get the java program). Somehow I am in a screen because when I do ^A d, I am brought to a new prompt.
Once I am out of the screen, screen -ls returns two instances of my-mc-server. One is a blank command prompt, the other is the server running successfully.
Edit 2: I changed startserver_command to remove the asterisk from env MC_PID=$! & (not needed there) and added it to (sleep 1; startserver_after) (makes it faster), redirected env line to /dev/null (removes entire environment listing at beginning of output). Still didn't fix the entire problem.
Instead of starting each screen session from the scripts, you can just use a custom .screenrc to specify some startup windows (and to run commands/scripts):
#$HOME/mc-server.screenrc
screen -t http-server 0 'startserver'
screen -t my-mc-server 1 'startserver_command'
screen -t gzip-logs 2 'startserver_after'
Then simply start screen (specifying the config file to use, if it's not the default ~/.screenrc)
screen -dm -c mc-server.screenrc
I have made a application launcher for Thunderbird (called mythunderbird) on a remote machine using the .XWinrc file.
menu apps {
xterm exec "xterm"
"Emacs" exec "emacs"
notepad exec notepad
xload exec "xload -display %display%" # Comment
mythunderbird exec "ssh -X mckserver.mckserver.apollo3.com thunderbird"
}
This starts beautifully with a multiple of keystrokes (right click XWin > (pint to Applicatoins) > click mythunderbird.
Can someone tell me how I can add such a menu to a desktop short cut? Putting a short cut to run "xterm" then logging in to the remote server and starting Thunderbird is easy, but a lot of steps and clicks.
What I really need to do is know what to change in this default short cut for starting xterm:
C:\cygwin\bin\run.exe -p /usr/X11R6/bin xterm -display 127.0.0.1:0.0 -ls
What I like about the functionality of the XWinrc application is that it has a clean execution of Thunderbird without the residue of an extra terminal left running. If I start it outside XWinrc, I have Thunderbird running, but also an extra xterm running.
The way I got it to work was to make a script in cygwin in my home directory (/home/dave/mythunderbird) which does the ssh call.
In the windows shortcut, set the target C:\cygwin\bin\run.exe bash -le /home/dave/mythunderbird
run.exe stops the command window being displayed and bash -le runs the script in bash from a login shell