From the outer session I'm using pane_cur="$(tmux display-message -p '#{pane_id}' | cut -c 2 | bc)" to control my pane switching behavior based on the pane in the inner session. Currently, I'm just getting the pane id of the outer session, and not the inner session.

Based on the outer pane id how can I drill down into a nested session, and get the pane id if one exists?

1 Answer 1


Preliminary note

In this answer I assume all tmux sessions exist within a single tmux server. If your outer and inner sessions belong to different tmux servers (running on the same or on different machines), then the situation is far more complicated and this answer does not apply.


In one tmux session (e.g. the outer session), to get some information from another tmux session (e.g. the inner session), you need to target the other session. In many tmux commands (including display-message) you can use -t and specify a target.

If you know your inner session is 1 then this command:

tmux display-message -t 1: -p '#{pane_id}'

will give you the ID of the currently active pane in the current window in the inner session.

If you don't know what number (or session name) to use then you need to ask tmux. I guess this is what you mean by "drill down".


You can do it like this:

  1. Suppose tmux display-message -p '#{pane_id}' gave you %5. It's the active pane in the outer session.

  2. You don't really need the ID of this pane. You need the tty tmux created for processes in the pane. You can get it with tmux display-message -p '#{pane_tty}' E.g. it may be /dev/pts/2.

  3. Assuming in the pane there is a tmux client attached to an inner session, you need to find the session of the client that uses the tty. Invoke tmux list-clients -F '#{client_tty} #{client_session}'. Its output may be like:

    /dev/pts/1 foo
    /dev/pts/2 1

    Now you know the session that uses /dev/pts/2 is 1.

  4. Identify the active pane in this session:

    tmux display-message -t 1: -p '#{pane_id}'
  5. If you want to drill deeper (because there is yet another nested session) then go to (2), but this time you need to target the pane we just learned.

Example shell code


pane="$(tmux display-message -p '#{pane_id}')" || exit 1

   tty="$(tmux display-message -t "$pane" -p '#{pane_tty}')"
      tmux list-clients -F '#{client_tty} #{client_session}' \
      | grep "^$tty " | head -n 1 | cut -d ' ' -f 2-
   [ -n "$session" ]
   pane="$(tmux display-message -t "$session:" -p '#{pane_id}')"

printf '%s\n' "$pane"

The code does not try to handle all errors. In particular, if a pane or a session is destroyed when the code works, information (like $session) from one invocation of tmux may be invalid when used with the next invocation of tmux.

I tested the code by saving as scrpt, making it executable and running watch ./scrpt in a shell in my most outer tmux session. In my tests I created up to three additional levels of nested tmux, but the code is designed to deal with any depth.

Side note

printf '%s\n' "${pane#%}" will give you a number without the leading %, if this is what you want. But remember in tmux pane_id is unique and represented with %, pane_index is not unique and represented without %. If you remove % from what pane_id returns and later use the number in tmux (without re-adding %) then it will probably be interpreted as pane_index.

  • They're two different machines running their own tmux. I attach to the other machine's tmux after entering with ssh.
    – ZeroPhase
    Commented Jun 9, 2022 at 7:16
  • @ZeroPhase It's a shame you did not mention this in the question. BTW, what is the point of knowing the ID of a remote tmux pane in a local script? Locally it means nothing. To use it remotely, while operating locally, you need as complicated contraption as to get it in the first place. I think there's an XY problem here. What do you need the remote ID locally for? Commented Jun 9, 2022 at 7:23
  • I have my remote machine split into two panes. I ssh in from a local pane. I'm trying to be able to move from the inner panes to the outer panes. My previous movement implementation just moved around the outer panes. My current implementation just moves around the inner panes.
    – ZeroPhase
    Commented Jun 9, 2022 at 7:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .