Reputation: 8607
I want to use a script to open a tmux session with 6 windows, each in a different directory. I started with a script I found and tried this first:
tmux new-session -s xyz -n etc -d 'cd /etc'
tmux new-window -t xyz:1 -n var 'cd /var/log'
But I soon found out that this will not work as I expected — the window will be closed after the shell command completes.
So my next idea was to start a new shell like this:
tmux new-session -s xyz -n etc -d 'cd /etc; bash -i'
tmux new-window -t xyz:1 -n var 'cd /var/log; bash -i'
tmux new-window -t xyz:2 -n var2 'cd /var/log; bash -i'
tmux new-window -t xyz:3 -n var3 'cd /var/log; bash -i'
tmux new-window -t xyz:4 -n var4 'cd /var/log; bash -i'
tmux new-window -t xyz:5 -n var5 'cd /var/log; bash -i'
tmux new-window -t xyz:6 -n var6 'cd /var/log; bash -i'
tmux select-window -t xyz:1
tmux -2 attach-session -t xyz
This almost works. But if I start more than about 4 windows, I frequently see the following bash errors in one of the windows after startup:
bash: [: =: unary operator expected
bash: [: too many arguments
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: too many arguments
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: =: unary operator expected
bash: [: =: unary operator expected
I have no idea why this happens, but I still think that I’m not doing this right. Is there a better way to set up a tmux session over several directories?
Upvotes: 43
Views: 61593
Reputation: 5041
This works for me . Each pane opens in a different directory
alias tmx='tmux new-session -c ~/Pictures \; split-window -v -c /intranet/homenote/ \; split-window -h -c ~/Videos/ \;'
Upvotes: 1
Reputation: 18199
For those who don't have ruby tmuxp is available in Python and supports both Teamocil and Tmuxinator style configuration files (in both yaml and json).
Not to mention there is a very sweet library behind it all https://github.com/tmux-python/libtmux
pip:
pip install --user tmuxp
Above: Add ~/.local/bin/
to your $PATH
for python user install programs
apt (Debian / Ubuntu / Mint):
sudo apt install tmuxp
Brew:
brew install tmuxp
Configuration
# ~/.tmuxp/workbench.yaml
session_name: workbench
windows:
- name: workbench
layout: main-vertical
panes:
- vim
- pane
- pane
tmuxp load workbench
You can load sessions directly: e.g. tmuxp load ./myworkspace.yaml
And finally, in your project-based config:
# tmuxp file aat project/.tmuxp.yaml
tmuxp load ./project
See documentation on tmuxp load
for more information.
More configuration examples: https://tmuxp.git-pull.com/configuration/examples.html
Upvotes: 11
Reputation: 4904
To simply open tmux with multiple panes and run some commands, I created the following bash file:
#!/bin/bash
tmux split-window -v -p 30 -c ~/path/to/folder1
tmux split-window -h -p 66 -c ~/path/to/folder2
tmux split-window -h -p 50 'mongod'
Run the bash file to get the following:
-----------------------------------
| |
|---------------------------------|
| folder1 | folder2 | mongod |
-----------------------------------
Upvotes: 1
Reputation: 3096
I could not for the life of me get -c to work, so I worked around this by creating a script that is ran via send - this allows me to do whatever I want in each tmux session. In case it helps someone else, here it is:
#!/bin/bash
TMUX_SESSION=mystuff
TOP=~/mydir
tmux new-session -s "$TMUX_SESSION" -n $(pwd) -d
launch_my_window()
{
WINDOW=$1
NAME=$2
SUBDIR=$3
SCRIPT=$TMPDIR/tmux.sh.$WINDOW.$NAME
tmux new-window -t "$TMUX_SESSION:$WINDOW" -n "$NAME"
cat >$SCRIPT <<%%
cd $TOP/$SUBDIR
# do more stuff here
%%
chmod +x $SCRIPT
tmux send -t "$TMUX_SESSION:$WINDOW" $SCRIPT ENTER
sleep 1
}
launch_my_window 1 "stuff" subdir1
launch_my_window 2 "morestuff" subdir2
launch_my_window 3 "yetmorestuff" subdir3
#...
# Select window #1 and attach to the WINDOW
tmux select-window -t "$TMUX_SESSION:1"
tmux -2 attach-session -t "$TMUX_SESSION"
Upvotes: 3
Reputation: 5021
You can use Teamocil instead. Teamocil is a simple tool used to automatically create sessions, windows and panes in tmux with YAML files.
Upvotes: 9
Reputation: 4386
Tmuxinator is also really good for this. Basically you create setup files like so:
# ~/.tmuxinator/project_name.yml
# you can make as many tabs as you wish...
project_name: Tmuxinator
project_root: ~/code/rails_project
socket_name: foo # Not needed. Remove to use default socket
rvm: 1.9.2@rails_project
pre: sudo /etc/rc.d/mysqld start
tabs:
- editor:
layout: main-vertical
panes:
- vim
- #empty, will just run plain bash
- top
- shell: git pull
- database: rails db
- server: rails s
- logs: tail -f logs/development.log
- console: rails c
- capistrano:
- server: ssh me@myhost
Then you can start a new session with:
mux project_name
I've been using it for a while and have had a good experience for the most part.
Upvotes: 35
Reputation: 225037
The shell errors are probably due to some problem in your startup files (or something they run).
As shellter commented, temporarily including the command set -vx
early in your startup sequence is a good way to find out where the errors are occurring.
If you find the -vx
output too verbose, you could try “printf debugging” (manually adding debug statements to your startup files until you can narrow down exactly which lines are causing the errors):
echo start of .bashrc
and echo end of .bashrc
at the start/end of your .bashrc
to see if the error occurs during your .bashrc
. If not, instrument your other startup files: .bash_profile
/.bash_login
/.profile
. If the errors happen before that file, then the problem may be in /etc/profile
.Note: These debug additions need to be temporary since they will cause problems if you ever use a program that makes automated logins (e.g. rsync, SSH-based Git access, etc.) since these programs expect a “clean” connection without such debugging noise present.
There should be no need to use cd
command like that in the shell-command argument given to either tmux new-session
or tmux new-window
.
A new window will “inherit”† the current working directory when using new-session
and new-window
from the command line (i.e. when done through the tmux
binary, instead of via a binding or at a tmux-:
prompt). According to the CHANGES file, it looks like this has been the case since tmux 0.6 (at least for new-window
).
† This is tmux-mediated inheritance, not the parent–child inheritance that is the usual mechanism for passing along the cwd.
This script works for me with tmux 1.5:
#!/bin/bash
# var for session name (to avoid repeated occurences)
sn=xyz
# Start the session and window 0 in /etc
# This will also be the default cwd for new windows created
# via a binding unless overridden with default-path.
cd /etc
tmux new-session -s "$sn" -n etc -d
# Create a bunch of windows in /var/log
cd /var/log
for i in {1..6}; do
tmux new-window -t "$sn:$i" -n "var$i"
done
# Set the default cwd for new windows (optional, otherwise defaults to session cwd)
#tmux set-option default-path /
# Select window #1 and attach to the session
tmux select-window -t "$sn:1"
tmux -2 attach-session -t "$sn"
This might also (as a side-effect) alleviate your shell startup errors since the way tmux starts a shell is different from a plain bash -i
(it is more akin to bash -l
, which uses your .bash_profile
/.bash_login
/.profile
instead of (just) your .bashrc
).
Upvotes: 29