Skip to content
← All notes

// notes

Linux: “command not found” — PATH, ifconfig, pip

command not found on Linux: how to trace a binary through PATH, why sudo and login shells see a different path, and what replaces ifconfig and pip

Published: 2026-10-095 min read
LinuxPATHcommand-not-foundbashifconfig

bash: ifconfig: command not found and bash: pip: command not found look like the same breakage, but the causes differ: in the first case the binary is not installed, in the second it is installed and its directory is missing from PATH. Below is how command lookup in PATH works and the type -a, command -v, echo $PATH, hash -r sequence that tells you what to fix

Symptom

The error appears when the shell finds the command in none of the directories listed in PATH. The wording depends on the shell and the locale; the meaning is the same

$ ifconfig
bash: ifconfig: command not found
$ pip --version
bash: pip: command not found
$ iptables -L
bash: iptables: command not found

iptables is here as an example of a command from /usr/sbin: under sudo it may run, while a regular user cannot start it. A similar-looking error shows up when a database is set up: PostgreSQL: connection refused and installing PostgreSQL

Diagnosis

Start by asking the shell where it looks for the command. command -v prints the path and returns 0 when the command is found, and prints nothing with exit code 1 when it is not

$ command -v ip
/usr/bin/ip
$ command -v ifconfig
$ echo $?
1

type -a lists every match: aliases, functions, builtins and binaries, in selection order

$ type -a python3
python3 is /usr/bin/python3
$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo

Next, inspect PATH itself: a colon-separated list of directories searched left to right

$ echo $PATH
/home/$USER/.local/bin:/usr/local/bin:/usr/bin:/bin
$ echo $PATH | tr ':' '\n'
/home/$USER/.local/bin
/usr/local/bin
/usr/bin
/bin

If the directory is not in the list, installing the package alone will not make the command visible. Check whether the binary is physically on disk

$ ls -l /usr/sbin/ifconfig 2>&1
ls: cannot access '/usr/sbin/ifconfig': No such file or directory

No file means the package is at fault. A file exists but the command is not found means PATH is at fault. One more source of confusion: bash caches resolved paths in a hash table, so a freshly installed command may stay invisible until hash -r

Cause

PATH is an environment variable read by the shell and by many programs. The first match wins, so directory order matters. If a directory is absent from the list, the command does not exist for the shell even when the file is on disk

On many systems /sbin and /usr/sbin are added to PATH for root only. A regular user does not see them, so iptables or visudo reports command not found while sudo iptables works

By default sudo resets the environment through env_reset and substitutes its own PATH from the secure_path directive in /etc/sudoers, which usually includes /usr/sbin

$ sudo env | grep '^PATH='
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

The second source of mismatch is the shell type. A login shell (SSH login, su -, bash --login) reads /etc/profile and ~/.bash_profile or ~/.profile. A non-login interactive shell (a terminal in a graphical session, plain bash) reads only ~/.bashrc. A PATH line added to just one of them will be missing in the other mode

The third cause is the command hash. Bash remembers the path to a binary it has resolved and does not re-read PATH, so a freshly installed command stays missing until hash -r or a new session

python3 -m pip is more reliable than pip: a system can have several Pythons, and a versionless pip points at the wrong one. The ~/.local/bin directory, where pip drops user scripts, is not in PATH by default either

Fix

The analysis leaves two scenarios. The package is not installed: install it. The command exists but its directory is not in PATH: add the directory

Scenario 1: ifconfig. On Debian and Ubuntu it ships in net-tools, which is not installed by default. The replacement is ip from iproute2

$ ip -brief address
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.0.2.10/24

If you specifically need the familiar ifconfig, for an old script:

$ sudo apt update
$ sudo apt install net-tools
$ sudo /usr/sbin/ifconfig -a

The full path sidesteps the PATH issue for the moment: under sudo the /usr/sbin directory is available through secure_path. Installing net-tools only for a manual check is not worth it; ip does more and is already present

Scenario 2: pip. On Debian and Ubuntu the package is python3-pip and it provides pip3. Run it as python3 -m pip to avoid mixing up interpreters

$ sudo apt update
$ sudo apt install python3-pip
$ python3 -m pip --version
pip <version> from .../dist-packages/pip (python 3.x)

On Fedora and RHEL the package is python3-pip, on Arch it is python-pip, and ip comes with iproute2. Verify package names with your distribution package manager

Scenario 3: ~/.local/bin. This is where scripts from pip install --user and standalone tools land. The directory is often missing from PATH; add it to ~/.profile for login shells and to ~/.bashrc for interactive ones

# ~/.profile and ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"

Apply it without re-logging in and reset the hash:

$ . ~/.bashrc
$ hash -r
$ command -v <tool>
/home/$USER/.local/bin/<tool>

hash -r affects only the current session: a new terminal starts with an empty hash. When the command must be available to all users, the directory is added through /etc/profile.d/*.sh, which is an administrator task. If the message is just command not found, the command-not-found package on Ubuntu prints the name of the package that provides the command

Verify

Verify with three commands: where the command is, what is in PATH, and whether the binary responds

$ command -v ifconfig || echo "not in PATH"
not in PATH
$ command -v pip3 || echo "not in PATH"
/usr/bin/pip3
$ ip -brief address
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.0.2.10/24

For ifconfig the output is empty: the net-tools binary lives in /usr/sbin, which is not in a regular user's PATH, so the || echo branch fires. The full path from the Fix section bypasses this: sudo /usr/sbin/ifconfig -a

PATH order and duplicates are easier to read line by line

$ echo $PATH | tr ':' '\n' | nl
     1  /home/$USER/.local/bin
     2  /usr/local/bin
     3  /usr/bin
     4  /bin

If command -v prints a path and returns 0, the command will run in this shell

$ command -v python3 >/dev/null && echo ok
ok

Pitfalls

  • `hash -r` only helps in the current shell. A new terminal re-reads PATH, so the edit from ~/.bashrc already applies there
  • A `PATH` line in `~/.bashrc` is invisible to non-interactive sessions. ssh host command, cron and systemd services do not read an interactive profile: they need ~/.profile, an Environment= directive in the unit file, or the full path to the program
  • `sudo` does not inherit your `PATH`. sudo -E works only when SETENV is allowed in sudoers; otherwise use sudo env "PATH=$PATH" <command> or the full path
  • `PATH` order decides. Putting $HOME/.local/bin before /usr/bin makes a same-named user command shadow the system one — sometimes exactly what you want, sometimes the source of mysterious failures
  • The system Python on Debian and Ubuntu is marked externally managed. A plain pip install fails with an externally-managed-environment error; user packages belong in venv or pipx, not sudo pip
  • Do not pull in `net-tools` blindly. Old scripts using ifconfig and netstat keep working, but new calls are better moved to ip and ss from iproute2

Takeaway

Command not found is one of two cases: the binary is absent, or its directory is missing from PATH. command -v and type -a reveal the first, echo $PATH the second, and hash -r resets the cache after an install. The login versus non-login shell difference explains why a command works in one terminal and disappears in another or under sudo

If you run many servers and keep hitting puzzles like this, see infrastructure as code. When the problem is in the application environment rather than the shell, backend and API development is the next step

Need this solved on your project?