Skip to main content
added 800 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129
  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • I used tput to determine the size of the current terminal. Then new-session -d -x … -y … uses proper values. But:
  • In my initial tests this seemed unnecessary, all worked without -x or -y
  • … although according to my local manual it should be necessary.
  • Anyway if the session already exists, its size is determined and new-session -d -x … -y … will have no impact. You may experience distorted proportions in the layout after you attach and the panes get resized. There are tmux commands and options that may help (resize-window, window-size, default-size), although not in my oldish tmux, so I won't elaborate.
  • tput operands lines and cols are not required by POSIX. See this answer for alternatives.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated and unsupported or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.
  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated and unsupported or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.
  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • I used tput to determine the size of the current terminal. Then new-session -d -x … -y … uses proper values. But:
  • In my initial tests this seemed unnecessary, all worked without -x or -y
  • … although according to my local manual it should be necessary.
  • Anyway if the session already exists, its size is determined and new-session -d -x … -y … will have no impact. You may experience distorted proportions in the layout after you attach and the panes get resized. There are tmux commands and options that may help (resize-window, window-size, default-size), although not in my oldish tmux, so I won't elaborate.
  • tput operands lines and cols are not required by POSIX. See this answer for alternatives.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated and unsupported or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.
added 75 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129
#!/bin/sh

session="$USER"
window="$session:1"

lines="$(tput lines)"
columns="$(tput cols)"

tmux -2 new-session -d -x "$columns" -y "$lines" -s "$session" 'echo "step -1"; bash'
tmux new-window -t "$window" -n 'Logs' 'echo "step 0"; bash' || exit

tmux split-window -t "$window"             -h -p 67    -d 'echo "step 1";  bash'
tmux split-window -t "$window"             -v -p 10 -b -d 'echo "step 2a"; bash'
tmux split-window -t "$window"             -v -p 22    -d 'echo "step 2b"; bash'
tmux split-window -t "$window"             -h -p 50       'echo "step 3";  bash'
tmux split-window -t "$window.{top-right}" -v -p 55    -d
tmux split-window -t "$window.{top-right}" -v -p 64
tmux select-pane  -t "$window.{bottom-right}"
tmux split-window -t "$window"             -v -p 67
tmux split-window -t "$window"             -v -p 50

tmux select-window -t "$window"

# Attach to session
tmux -2 attach-session -t "$session"
#!/bin/sh

session="$USER"
window="$session:1"

tmux -2 new-session -d -s "$session" 'echo "step -1"; bash'
tmux new-window -t "$window" -n 'Logs' 'echo "step 0"; bash' || exit

tmux split-window -t "$window"             -h -p 67    -d 'echo "step 1";  bash'
tmux split-window -t "$window"             -v -p 10 -b -d 'echo "step 2a"; bash'
tmux split-window -t "$window"             -v -p 22    -d 'echo "step 2b"; bash'
tmux split-window -t "$window"             -h -p 50       'echo "step 3";  bash'
tmux split-window -t "$window.{top-right}" -v -p 55    -d
tmux split-window -t "$window.{top-right}" -v -p 64
tmux select-pane  -t "$window.{bottom-right}"
tmux split-window -t "$window"             -v -p 67
tmux split-window -t "$window"             -v -p 50

tmux select-window -t "$window"

# Attach to session
tmux -2 attach-session -t "$session"
#!/bin/sh

session="$USER"
window="$session:1"

lines="$(tput lines)"
columns="$(tput cols)"

tmux -2 new-session -d -x "$columns" -y "$lines" -s "$session" 'echo "step -1"; bash'
tmux new-window -t "$window" -n 'Logs' 'echo "step 0"; bash' || exit

tmux split-window -t "$window"             -h -p 67    -d 'echo "step 1";  bash'
tmux split-window -t "$window"             -v -p 10 -b -d 'echo "step 2a"; bash'
tmux split-window -t "$window"             -v -p 22    -d 'echo "step 2b"; bash'
tmux split-window -t "$window"             -h -p 50       'echo "step 3";  bash'
tmux split-window -t "$window.{top-right}" -v -p 55    -d
tmux split-window -t "$window.{top-right}" -v -p 64
tmux select-pane  -t "$window.{bottom-right}"
tmux split-window -t "$window"             -v -p 67
tmux split-window -t "$window"             -v -p 50

tmux select-window -t "$window"

# Attach to session
tmux -2 attach-session -t "$session"
added 40 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129

One way to learn what the order may be is to draw the layout on a piece of paper and cut it with scissors with straight cuts that go through, so each cut divides the current piece into two smaller ones. Or imagine breaking a chocolate bar.

A possible scheme for your desired layout is like this:

  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated and unsupported or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.

One way to learn what the order may be is to draw the layout on a piece of paper and cut it with scissors with straight cuts that go through, so each cut divides the current piece into two smaller ones. A possible scheme for your desired layout is like this:

  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.

One way to learn what the order may be is to draw the layout on a piece of paper and cut it with scissors with straight cuts that go through, so each cut divides the current piece into two smaller ones. Or imagine breaking a chocolate bar.

A possible scheme for your desired layout is like this:

  • The shebang is /bin/sh, no need for Bash here.
  • Get used to double-quoting variables. It's way better to habitually quote regardless if you need it than forget to quote when it makes a real difference.
  • I used lowercase names for variables.
  • If window cannot be created, the script exits.
  • Each split-window targets the right window. If the session existed or someone attached in the meantime and changed the window, the current window would not be what you assume. To be even more robust each split-window should target a respective pane explicitly. Note that select-pane before split-window (or before resize-pane as in your script) is not really robust in a general setup where many clients can interact with the same tmux server: some other client (user or script) could select another pane between these two commands.
  • I do not resize panes. I create them with proper percentages in the first place. The -p option I use works in my oldish tmux. The documentation tells me the newer syntax is like split-window -l 20% and resize-pane can work with percentages as well. I don't know if the newest tmux understands split-window -p. The documentation doesn't mention this option any more, it may be deprecated and unsupported or it may be kept for compatibility; I cannot test this (feedback or edit is welcome).
  • split-window takes percentages that refer to the available space, i.e. to the old size of the pane that is about to shrink to make space for the new pane (at least this is how it works in my oldish tmux with -p). This is why numbers like 22 appear ( 20/(20+70) ≈ 22 ). According to the documentation resize-pane uses percentages of the window size.
  • I use or don't use -d to stay in the current pane or make the new one current, depending on which pane I need to target with the next split-window.
  • When I need to specify/select a pane that fits a token like {top-right}, I use the token.
  • I do not use send-keys to run commands. In general do not use send-keys to run commands. Any(?) tmux command that creates a new shell inside tmux can run a shell command instead. In the example script echo "step 0"; bash is such shell command. It includes bash at the end, so the pane doesn't exit when the actual command (echo) finishes. An alternative is the remain-on-exit option. Your shell commands (watch) can work indefinitely, so you may not need such tricks. Running a shell command with send-keys like you do in your script makes sense if the command affects the shell it runs in and your goal is to work interactively in the shell prepared this way. E.g. the command may set variables or source a script; or you want to be able to interrupt watch and have it in the shell history. In any other case the "right" way is to pass commands with split-window, respawn-pane or some similar tmux command.
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129
Loading