How can I start the gnome-terminal with multiple tabs with always the same title and history? - shell

I want to start the bash with 4 tabs, having different titles. In all of them I'm working in different directories so it would be useful if I can cd to different paths.
Now it would be also great to save the history separately for every tab. So that every tab only remembers the commands I ran on it, even after a reboot.
Currently I have a script which starts gnome-terminal with 4 tabs.
gnome-terminal --geometry=150x50 --tab --title="src" -e "bash -c \"cd "~/path/to/src";exec bash\"" --tab --title="first test" -e "bash -c \"cd "~/path/to/single-test-dir";exec bash\"" --tab --title="test3" -e "bash -c \"cd "~/path/to/testdir";exec bash\"" --tab --title="test4" -e "bash -c \"cd "~/path/to/somewhere";exec bash\""

I suppose you can use a gnome-terminal custom command for each profile, for example
bash -c 'PROFILE=default_profile exec bash'
or
bash -c 'PROFILE=screen_profile exec screen -U'
or similar.
Then in ~/.bashrc
if [[ -n $PROFILE ]]; then
HISTFILE=~/.bash_history."$PROFILE"
fi
source of the answer.

Related

How to run tmux with shell command

I want to run tmux with shell command in it
I try:
tmux new-session -d -s foo 'echo intmux'
( I want to use this later in bash script)
But it doesn't works. I expect that:
1) Tmux open new window ( like tmux new )
2) command echo intmux will be called
1) Tmux open new window ( like tmux new )
You will not see a new session, because you create it using -d (detached) flag.
What you want (execute a command and leave a shell open) can be easily achieved with:
tmux new -s foo 'echo intmux; $SHELL'
Another tricky option bound to specific (bash) shell:
tmux new-session -s foo 'bash --rcfile <(echo ". ~/.bashrc; echo intmux")'
This allows to preserve default behavior (reading . ~/.bashrc) and pass your arbitrary command.
You can run
tmux new-session '-s foo' \; neww '-t 2 -n echo' mc
But that spawns another window in the new session running your command so possibly you want to close the first window
tmux new-session '-s foo' \; neww '-n echo' mc \; kill-window '-t 1'

Bash: Execute command WITH ARGUMENTS in new terminal [duplicate]

This question already has answers here:
how do i start commands in new terminals in BASH script
(2 answers)
Closed 20 days ago.
So i want to open a new terminal in bash and execute a command with arguments.
As long as I only take something like ls as command it works fine, but when I take something like route -n , so a command with arguments, it doesnt work.
The code:
gnome-terminal --window-with-profile=Bash -e whoami #WORKS
gnome-terminal --window-with-profile=Bash -e route -n #DOESNT WORK
I already tried putting "" around the command and all that but it still doesnt work
You can start a new terminal with a command using the following:
gnome-terminal --window-with-profile=Bash -- \
bash -c "<command>"
To continue the terminal with the normal bash profile, add exec bash:
gnome-terminal --window-with-profile=Bash -- \
bash -c "<command>; exec bash"
Here's how to create a Here document and pass it as the command:
cmd="$(printf '%s\n' 'wc -w <<-EOF
First line of Here document.
Second line.
The output of this command will be '15'.
EOF' 'exec bash')"
xterm -e bash -c "${cmd}"
To open a new terminal and run an initial command with a script, add the following in a script:
nohup xterm -e bash -c "$(printf '%s\nexec bash' "$*")" &>/dev/null &
When $* is quoted, it expands the arguments to a single word, with each separated by the first character of IFS. nohup and &>/dev/null & are used only to allow the terminal to run in the background.
Try this:
gnome-terminal --window-with-profile=Bash -e 'bash -c "route -n; read"'
The final read prevents the window from closing after execution of the previous commands. It will close when you press a key.
If you want to experience headaches, you can try with more quote nesting:
gnome-terminal --window-with-profile=Bash \
-e 'bash -c "route -n; read -p '"'Press a key...'"'"'
(In the following examples there is no final read. Let’s suppose we fixed that in the profile.)
If you want to print an empty line and enjoy multi-level escaping too:
gnome-terminal --window-with-profile=Bash \
-e 'bash -c "printf \\\\n; route -n"'
The same, with another quoting style:
gnome-terminal --window-with-profile=Bash \
-e 'bash -c '\''printf "\n"; route -n'\'
Variables are expanded in double quotes, not single quotes, so if you want them expanded you need to ensure that the outermost quotes are double:
command='printf "\n"; route -n'
gnome-terminal --window-with-profile=Bash \
-e "bash -c '$command'"
Quoting can become really complex. When you need something more advanced that a simple couple of commands, it is advisable to write an independent shell script with all the readable, parametrized code you need, save it somewhere, say /home/user/bin/mycommand, and then invoke it simply as
gnome-terminal --window-with-profile=Bash -e /home/user/bin/mycommand

compound command with bash -c in tmux vs screen

I need to run a command with bash -c within a tmux session, from within a shell script. In contrast to screen, tmux seems to require to quote the entire command, which leads to problems as bash -c also requires quoting for correct functioning with more complex command strings.
In the following I'm trying to demonstrate the behavior with a minimal example. What I'm trying to achieve involves more complex commands than ls of course. Also for my purpose it is necessary to expand the CMD variable, as it is built in the script before.
A minimal script for screen:
#!/bin/bash
set -x
CMD="ls -l; sleep 5"
screen -d -m bash -c "$CMD"
When executing this script you get (stdout due to -x)
+ CMD='ls -l; sleep 5'
+ screen -d -m bash -c 'ls -l; sleep 5'
The sleep command is for having time to attach to the screen session and see what happens. When attaching to the screen session after executing the above script one sees that the output of the ls command is in long list format, i.e. the command is executed properly.
In tmux it seems one has to quote the command to get it executed in the new session. I use the following script:
#!/bin/bash
set -x
CMD="ls -l; sleep 5"
tmux new -d "bash -c $CMD"
The stdout is
+ CMD='ls -l; sleep 5'
+ tmux new -d 'bash -c ls -l; sleep 5'
As one can see, the cmd sequence for bash -c is not quoted properly anymore. When attaching to the created tmux session one can see, that this results in ls being executed without the long list option recognized.
What can I do to get the proper quoting (i.e. single quotes around the expanded string) for the $CMD string passed to bash -c?
Update
Escaping, as Eric Renouf suggested, with \"$CMD\" produces
tmux new -d 'bash -c "ls -l; sleep 5"'
and escaping with '$CMD' produces
tmux new -d 'bash -c '\''ls -l; sleep 5'\'''
Both works for the provided minimal example, but is still not exactly what screen produces and does not work in my case.
Here are the exact call I'm making (see here for all the gory details):
$SCREEN -S "scalaris_$NODE_NAME" -d -m bash -x -f +B -c "$START_CMD; sleep 365d"
which produces (output of -x)
/usr/bin/screen -S scalaris_first#pvs-pc07.zib.de -d -m bash -x -f +B -c '"/usr/bin/erl" -setcookie "chocolate chip cookie" -pa /home/jvf/code/scalaris/contrib/yaws/ebin -pa /home/jvf/code/scalaris/contrib/log4erl/ebin -pa /home/jvf/code/scalaris/ebin -sasl sasl_error_logger false -yaws embedded true -scalaris log_path "\"/home/jvf/code/scalaris/log/first#pvs-pc07.zib.de\"" -scalaris docroot "\"/home/jvf/code/scalaris/docroot\"" -scalaris config "\"/home/jvf/code/scalaris/bin/scalaris.cfg\"" -scalaris local_config "\"/home/jvf/code/scalaris/bin/scalaris.local.cfg\"" -connect_all false -hidden -name first#pvs-pc07.zib.de -scalaris start_type first -scalaris port 14195 -scalaris yaws_port 8000 -scalaris join_at_list '\''[0]'\'' -scalaris start_mgmt_server true -scalaris nodes_per_vm "1" -s scalaris +sbt db +swt low +sbwt short'
I think the solutions suggested so far do not work because of the use of double quotes within the command, but I'm not 100% positive about that. How can I reproduce the exact quoting screen produces (single quotes around the complete command passed to bash -c) with tmux?
I'm trusting that you need to do this for tmux, but to get the extra quotes you want, you could just escape them in the outer quote like:
tmux new -d "bash -c \"$CMD\""
or you could put those in single quotes in most cases like
tmux new -d "bash -c '$CMD'"
since the $CMD will be expanded by the outer quotes

How to execute multiple commands after opening a new terminal tab

I need to open a new terminal tab and execute multiple commands on it, how can I do it. I have already tried the following,
gnome-terminal --tab -t "X" -e "cd ~/Desktop/terminal_test;mkdir test"
Here I need to cd into a new directory and create a new folder.
Try this:
gnome-terminal -x bash -c "cmd1; cmd2; …cmdN; exec bash"
You can use gnome-terminal. The script below will open 3 tabs running the respective commands..
tab="--tab"
cmd01="bash -c 'ls';'pwd';bash"
foo=""
foo+=($tab -e "$cmd01")
gnome-terminal "${foo[#]}"
exit 0

How do I run nohup as a different user without spawning two processes?

I'm trying to nohup a command and run it as a different user, but every time I do this two processes are spawned.
For example:
$ nohup su -s /bin/bash nobody -c "my_command" > outfile.txt &
This definitely runs my_command as nobody, but there's an extra process that I don't want to shown up:
$ ps -Af
.
.
.
root ... su -s /bin/bash nobody my_command
nobody ... my_command
And if I kill the root process, the nobody process still lives... but is there a way to not run the root process at all? Since getting the id of my_command and killing it is a bit more complicated.
This could be achieved as:
su nobody -c "nohup my_command >/dev/null 2>&1 &"
and to write the pid of 'my_command' in a pidFile:
pidFile=/var/run/myAppName.pid
touch $pidFile
chown nobody:nobody $pidFile
su nobody -c "nohup my_command >/dev/null 2>&1 & echo \$! > '$pidFile'"
nohup runuser nobody -c "my_command my_command_args....." < /dev/null >> /tmp/mylogfile 2>&1 &
If the user with nologin shell, run as follows:
su - nobody -s /bin/sh -c "nohup your_command parameter >/dev/null 2>&1 &"
Or:
runuser - nobody -s /bin/sh -c "nohup your_command parameter >/dev/null 2>&1 &"
Or:
sudo su - nobody -s /bin/sh -c "nohup your_command parameter >/dev/null 2>&1 &"
sudo runuser -u nobody -s /bin/sh -c "nohup your_command parameter >/dev/null 2>&1 &"
You might do best to create a small script in e.g. /usr/local/bin/start_my_command like this:
#!/bin/bash
nohup my_command > outfile.txt &
Use chown and chmod to set it to be executable and owned by nobody, then just run su nobody -c /usr/local/bin/start_my_command.
A note on running this on a session, is that if you run in background, there is a job associated with the session, and background jobs may be killed (the su -c gets around this).
To disassociate the process from the shell (so you can exit the shell but keep the process running), use disown.

Resources