How to open Nautilus directory in current Terminal?

I don't like to have dozens of terminals opened. Is there a way to add Open in current Terminal instead of Open in Terminal when using Nautilus?


Solution 1:

Dirty or not, the solution below worked perfectly in the 30 minutes I tested it frequently. The solution works as long as you can right-click a file (any) inside the directory:

1.

enter image description here

2.

enter image description here

3.

enter image description here

Nautilus script

#!/usr/bin/env python3
import subprocess
import os
import time

def replace(path):
    for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
              ("file://", ""), ("%20", " ")]:
        path = path.replace(c[0], c[1])
    return path

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

t = get(["pgrep", "gnome-terminal"])
if t:
    w = [l.split()[0] for l in get(["wmctrl", "-lp"]).splitlines() if t in l][0]
    # get the current path
    current = replace(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
    dr = os.path.realpath(current)
    # raise the found terminal window
    subprocess.call(["wmctrl", "-ia", w])
    time.sleep(0.3)
    # copy the cd command to clipboard
    c1 = "printf 'cd ' | xclip -in -selection c"
    c2 = 'echo "'+"'"+dr+"'"+'"  | xclip -in -selection c'
    # paste & run it
    for c in [c1, c2]:
        subprocess.call(["/bin/bash", "-c", c])
        subprocess.call(["xdotool", "key", "Control_L+Shift+v"])
        time.sleep(0.05)

How to use

  1. The script needs wmctrl, xdotool and xclip:

    sudo apt-get install wmctrl xdotool xclip
    
  2. Copy the script into an empty file, save it as open_in_terminal (no extension) in ~/.local/share/nautilus/scripts. Create the directory if needed. Make the script executable

That's it. Log out and back in and you'll have the script available as in the image (2).

Explanation

  • Right- clicking a file, we can get the path using nautilus' "NAUTILUS_SCRIPT_CURRENT_URI".
  • In a script, we can then load this path into the clipboard (using xclip)
  • Subsequently, the script raises the (first found) gnome-terminal window and pastes the path, preceded by the cd command. Since we used echo to load the whole line into the clipboard, Return is included.

Notes

  1. It should be clear that there should be nothing running in the terminal, and it works best if there is only one terminal window open. In case there are multiple, the script picks the oldest gnome-terminal window.
  2. The script needs to be tested thoroughly in practice. While I ran it, the timing was no issue even a single time, not even when the Desktop had to "travel" across four or five viewports to get to the terminal window. IF errors would occur however, with a few lines more we could make it actually wait in a smart(er) way for the terminal window to be raised. Let's see what happens. It doesn't seem necessary.
  3. Since the script uses the realpath, also linked directories will work correctly.

More information on nautilus scripts here.


Alternatively, pick your own terminal window if you have multiple

If you want to be able to choose in which terminal window you would open the current (nautilus) directory, use the script below.

How it works in practice

  1. Right- click (any) file inside the directory (in this case my desktop) like below:

    enter image description here

  2. Click on (or raise otherwise) the terminal window you'd like to use, and it will cd to the directory:

    enter image description here

The script

#!/usr/bin/env python3
import subprocess
import os
import time

def replace(path):
    for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
              ("file://", ""), ("%20", " ")]:
        path = path.replace(c[0], c[1])
    return path

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

# check if gnome-terminal runs
pid = get(["pgrep", "gnome-terminal"])

if pid:
    t = 0
    while t < 30:
        # see if the frontmost window is a terminam window
        active = get(["xdotool", "getactivewindow"])
        if pid in get(["xprop", "-id", active]):       
            # get the current path
            current = replace(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
            dr = os.path.realpath(current)
            # copy the cd command to clipboard
            c1 = "printf 'cd ' | xclip -in -selection c"
            c2 = 'echo "'+"'"+dr+"'"+'"  | xclip -in -selection c'
            # paste & run it
            for c in [c1, c2]:
                subprocess.call(["/bin/bash", "-c", c])
                subprocess.call(["xdotool", "key", "Control_L+Shift+v"])
                time.sleep(0.05)
            break
        else:
            t += 1
            time.sleep(0.5)

Setup

Is exactly like the first script.

Explanation

The script has one difference from the first one: instead of automatically raising the first found terminal window, it waits for the first terminal window to have focus. Then it cd's to the directory inside that window.

Solution 2:

Simplest way is this:

  1. From nautilus, press Ctrl + L , this will open the address bar for editing. Press the Ctrl+C
  2. Switch to terminal and type in cd, space, then Shift + Insert (or INS) to paste the path. Hit Enter.

No need for scripts or extra work.

Solution 3:

I'm pretty sure there's no way to do this, however I have a workaround for you that might help.

You can always drag and drop a directory from Nautilus into a terminal window and Nautilus will pass that directory and paste it into the command line, so you could do cd and then drag the folder onto the terminal and hit enter.

Solution 4:

In my opinion the only elegant way to solve this without fuding around is to use a terminal multiplexer like tmux and have your file manager

  • open new terminal windows inside an existing session or
  • start a new terminal emulator with a new tmux session.

The following shell script achieves just that:

#!/bin/sh
set -e
TMUX=tmux
#TERMINAL_EMULATOR='gnome-terminal -x'

cd "$1"
if $TMUX has-session; then
  exec $TMUX new-window
else
  exec ${TERMINAL_EMULATOR:-x-terminal-emulator -x} $TMUX
fi

TERMINAL_EMULATOR holds the desired terminal emulator for new terminal windows (if you don't like the default of whatever x-terminal-emulator points to) plus a command-line option for the command to execute inside the emulator.

You can register the file handler script like any other file type association in your file manager.