Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here


Magnificent app which corrects your previous console command.

Subscribe to updates I use thefuck

Statistics on thefuck

Number of watchers on Github 34199
Number of open issues 143
Average time to close an issue 16 days
Main language Python
Average time to merge a PR 3 days
Open pull requests 29+
Closed pull requests 10+
Last commit over 2 years ago
Repo Created about 5 years ago
Repo Last Updated about 2 years ago
Size 2.56 MB
Organization / Authornvbn
Latest Release3.25
Page Updated
Do you use thefuck? Leave a review!
View open issues (143)
View thefuck activity
View on github
Fresh, new opensource launches πŸš€πŸš€πŸš€
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating thefuck for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

The Fuck Version Build Status Windows Build Status Coverage MIT License

Magnificent app which corrects your previous console command, inspired by a @liamosaur tweet.

The Fuck is too slow? Try experimental instant mode!

gif with examples

Few more examples:

 apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

sudo apt-get install vim [enter///ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
 git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

git push --set-upstream origin master [enter///ctrl+c]
Counting objects: 9, done.
No command 'puthon' found, did you mean:
 Command 'python' from package 'python-minimal' (main)
 Command 'python' from package 'python3' (main)
zsh: command not found: puthon

python [enter///ctrl+c]
Python 3.4.2 (default, Oct  8 2014, 13:08:17)
 git brnch
git: 'brnch' is not a git command. See 'git --help'.

Did you mean this?

git branch [enter///ctrl+c]
* master
 lein rpl
'rpl' is not a task. See 'lein help'.

Did you mean this?

lein repl [enter///ctrl+c]
nREPL server started on port 54848 on host - nrepl://
REPL-y 0.3.1

If you are not scared to blindly run the changed command, there is a require_confirmation settings option:

 apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done


  • python (3.4+)
  • pip
  • python-dev


On OS X you can install The Fuck with Homebrew:

brew install thefuck

On Ubuntu you can install The Fuck with:

sudo apt update
sudo apt install python3-dev python3-pip
sudo pip3 install thefuck

On FreeBSD you can install The Fuck with:

sudo portsnap fetch update
cd /usr/ports/misc/thefuck && sudo make install clean

On other systems you can install The Fuck with pip:

pip install thefuck

Or using an OS package manager (OS X, Ubuntu, Arch).

# You should place this command in your .bash_profile, .bashrc, .zshrc or other startup script:

eval $(thefuck --alias)
# You can use whatever you want as an alias, like for Mondays:
eval $(thefuck --alias FUCK)

Or in your shell config (Bash, Zsh, Fish, Powershell, tcsh).

Changes will be available only in a new shell session. To make them available immediately, run source ~/.bashrc (or your shell config file like .zshrc).

If you want to run fixed command without confirmation you can use -y option:

fuck -y

If you want to fix commands recursively until success you can use -r option:

fuck -r


pip3 install thefuck --upgrade

Aliases changed in 1.34.

How it works

The Fuck tries to match a rule for the previous command, creates a new command using the matched rule and runs it. Rules enabled by default are as follows:

  • adb_unknown_command – fixes misspelled commands like adb logcta;
  • ag_literal – adds -Q to ag when suggested;
  • aws_cli – fixes misspelled commands like aws dynamdb scan;
  • cargo – runs cargo build instead of cargo;
  • cargo_no_command – fixes wrongs commands like cargo buid;
  • cd_correction – spellchecks and correct failed cd commands;
  • cd_mkdir – creates directories before cd'ing into them;
  • cd_parent – changes cd.. to cd ..;
  • chmod_x – add execution bit;
  • composer_not_command – fixes composer command name;
  • cp_omitting_directory – adds -a when you cp directory;
  • cpp11 – adds missing -std=c++11 to g++ or clang++;
  • dirty_untar – fixes tar x command that untarred in the current directory;
  • dirty_unzip – fixes unzip command that unzipped in the current directory;
  • django_south_ghost – adds --delete-ghost-migrations to failed because ghosts django south migration;
  • django_south_merge – adds --merge to inconsistent django south migration;
  • docker_not_command – fixes wrong docker commands like docker tags;
  • dry – fixes repetitions like git git push;
  • fab_command_not_found – fix misspelled fabric commands;
  • fix_alt_space – replaces Alt+Space with Space character;
  • fix_file – opens a file with an error in your $EDITOR;
  • gem_unknown_command – fixes wrong gem commands;
  • git_add – fixes pathspec 'foo' did not match any file(s) known to git.;
  • git_add_force – adds --force to git add <pathspec>... when paths are .gitignore'd;
  • git_bisect_usage – fixes git bisect strt, git bisect goood, git bisect rset, etc. when bisecting;
  • git_branch_delete – changes git branch -d to git branch -D;
  • git_branch_exists – offers git branch -d foo, git branch -D foo or git checkout foo when creating a branch that already exists;
  • git_branch_list – catches git branch list in place of git branch and removes created branch;
  • git_checkout – fixes branch name or creates new branch;
  • git_commit_amend – offers git commit --amend after previous commit;
  • git_diff_no_index – adds --no-index to previous git diff on untracked files;
  • git_diff_staged – adds --staged to previous git diff with unexpected output;
  • git_fix_stash – fixes git stash commands (misspelled subcommand and missing save);
  • git_flag_after_filename – fixes fatal: bad flag '...' after filename
  • git_help_aliased – fixes git help <alias> commands replacing with the aliased command;
  • git_merge – adds remote to branch names;
  • git_merge_unrelated – adds --allow-unrelated-histories when required
  • git_not_command – fixes wrong git commands like git brnch;
  • git_pull – sets upstream before executing previous git pull;
  • git_pull_clone – clones instead of pulling when the repo does not exist;
  • git_pull_uncommitted_changes – stashes changes before pulling and pops them afterwards;
  • git_push – adds --set-upstream origin $branch to previous failed git push;
  • git_push_different_branch_names – fixes pushes when local brach name does not match remote branch name;
  • git_push_pull – runs git pull when push was rejected;
  • git_push_without_commits – Creates an initial commit if you forget and only git add ., when setting up a new project;
  • git_rebase_no_changes – runs git rebase --skip instead of git rebase --continue when there are no changes;
  • git_remote_delete – replaces git remote delete remote_name with git remote remove remote_name;
  • git_rm_local_modifications – adds -f or --cached when you try to rm a locally modified file;
  • git_rm_recursive – adds -r when you try to rm a directory;
  • git_rm_staged – adds -f or --cached when you try to rm a file with staged changes
  • git_rebase_merge_dir – offers git rebase (--continue | --abort | --skip) or removing the .git/rebase-merge dir when a rebase is in progress;
  • git_remote_seturl_add – runs git remote add when git remote set_url on nonexistant remote;
  • git_stash – stashes your local modifications before rebasing or switching branch;
  • git_stash_pop – adds your local modifications before popping stash, then resets;
  • git_tag_force – adds --force to git tag <tagname> when the tag already exists;
  • git_two_dashes – adds a missing dash to commands like git commit -amend or git rebase -continue;
  • go_run – appends .go extension when compiling/running Go programs;
  • gradle_no_task – fixes not found or ambiguous gradle task;
  • gradle_wrapper – replaces gradle with ./gradlew;
  • grep_arguments_order – fixes grep arguments order for situations like grep -lir . test;
  • grep_recursive – adds -r when you trying to grep directory;
  • grunt_task_not_found – fixes misspelled grunt commands;
  • gulp_not_task – fixes misspelled gulp tasks;
  • has_exists_script – prepends ./ when script/binary exists;
  • heroku_multiple_apps – add --app <app> to heroku commands like heroku pg;
  • heroku_not_command – fixes wrong heroku commands like heroku log;
  • history – tries to replace command with most similar command from history;
  • hostscli – tries to fix hostscli usage;
  • ifconfig_device_not_found – fixes wrong device names like wlan0 to wlp2s0;
  • java – removes .java extension when running Java programs;
  • javac – appends missing .java when compiling Java files;
  • lein_not_task – fixes wrong lein tasks like lein rpl;
  • ln_no_hard_link – catches hard link creation on directories, suggest symbolic link;
  • ln_s_order – fixes ln -s arguments order;
  • ls_all – adds -A to ls when output is empty;
  • ls_lah – adds -lah to ls;
  • man – changes manual section;
  • man_no_space – fixes man commands without spaces, for example mandiff;
  • mercurial – fixes wrong hg commands;
  • missing_space_before_subcommand – fixes command with missing space like npminstall;
  • mkdir_p – adds -p when you trying to create directory without parent;
  • mvn_no_command – adds clean package to mvn;
  • mvn_unknown_lifecycle_phase – fixes misspelled lifecycle phases with mvn;
  • npm_missing_script – fixes npm custom script name in npm run-script <script>;
  • npm_run_script – adds missing run-script for custom npm scripts;
  • npm_wrong_command – fixes wrong npm commands like npm urgrade;
  • no_command – fixes wrong console commands, for example vom/vim;
  • no_such_file – creates missing directories with mv and cp commands;
  • open – either prepends http:// to address passed to open or create a new file or directory and passes it to open;
  • pip_unknown_command – fixes wrong pip commands, for example pip instatl/pip install;
  • php_s – replaces -s by -S when trying to run a local php server;
  • port_already_in_use – kills process that bound port;
  • prove_recursively – adds -r when called with directory;
  • python_command – prepends python when you trying to run not executable/without ./ python script;
  • python_execute – appends missing .py when executing Python files;
  • quotation_marks – fixes uneven usage of ' and " when containing args';
  • path_from_history – replaces not found path with similar absolute path from history;
  • react_native_command_unrecognized – fixes unrecognized react-native commands;
  • remove_trailing_cedilla – remove trailling cedillas ``, a common typo for european keyboard layouts;
  • rm_dir – adds -rf when you trying to remove directory;
  • scm_correction – corrects wrong scm like hg log to git log;
  • sed_unterminated_s – adds missing '/' to sed's s commands;
  • sl_ls – changes sl to ls;
  • ssh_known_hosts – removes host from known_hosts on warning;
  • sudo – prepends sudo to previous command if it failed because of permissions;
  • sudo_command_from_user_path – runs commands from users $PATH with sudo;
  • switch_lang – switches command from your local layout to en;
  • systemctl – correctly orders parameters of confusing systemctl;
  • test.py – runs py.test instead of test.py;
  • touch – creates missing directories before touching;
  • tsuru_login – runs tsuru login if not authenticated or session expired;
  • tsuru_not_command – fixes wrong tsuru commands like tsuru shell;
  • tmux – fixes tmux commands;
  • unknown_command – fixes hadoop hdfs-style unknown command, for example adds missing '-' to the command on hdfs dfs ls;
  • unsudo – removes sudo from previous command if a process refuses to run on super user privilege.
  • vagrant_up – starts up the vagrant instance;
  • whois – fixes whois command;
  • workon_doesnt_exists – fixes virtualenvwrapper env name os suggests to create new.
  • yarn_alias – fixes aliased yarn commands like yarn ls;
  • yarn_command_not_found – fixes misspelled yarn commands;
  • yarn_command_replaced – fixes replaced yarn commands;
  • yarn_help – makes it easier to open yarn documentation;

Enabled by default only on specific platforms:

  • apt_get – installs app from apt if it not installed (requires python-commandnotfound / python3-commandnotfound);
  • apt_get_search – changes trying to search using apt-get with searching using apt-cache;
  • apt_invalid_operation – fixes invalid apt and apt-get calls, like apt-get isntall vim;
  • apt_list_upgradable – helps you run apt list --upgradable after apt update;
  • apt_upgrade – helps you run apt upgrade after apt list --upgradable;
  • brew_cask_dependency – installs cask dependencies;
  • brew_install – fixes formula name for brew install;
  • brew_link – adds --overwrite --dry-run if linking fails;
  • brew_uninstall – adds --force to brew uninstall if multiple versions were installed;
  • brew_unknown_command – fixes wrong brew commands, for example brew docto/brew doctor;
  • brew_update_formula – turns brew update <formula> into brew upgrade <formula>;
  • dnf_no_such_command – fixes mistyped DNF commands;
  • pacman – installs app with pacman if it is not installed (uses yaourt if available);
  • pacman_not_found – fixes package name with pacman or yaourt.

Bundled, but not enabled by default:

  • git_push_force – adds --force-with-lease to a git push (may conflict with git_push_pull);
  • rm_root – adds --no-preserve-root to rm -rf / command.

Creating your own rules

For adding your own rule you should create your-rule-name.py in ~/.config/thefuck/rules. The rule should contain two functions:

match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]

Also the rule can contain an optional function

side_effect(old_command: Command, fixed_command: str) -> None

and optional enabled_by_default, requires_output and priority variables.

Command has three attributes: script, output and script_parts. Rule shouldn't change Command.

Rules api changed in 3.0: For accessing settings in rule you need to import it with from thefuck.conf import settings. settings is a special object filled with ~/.config/thefuck/settings.py and values from env (see more below).

Simple example of the rule for running script with sudo:

def match(command):
    return ('permission denied' in command.output.lower()
            or 'EACCES' in command.output)

def get_new_command(command):
    return 'sudo {}'.format(command.script)

# Optional:
enabled_by_default = True

def side_effect(command, fixed_command):
    subprocess.call('chmod 777 .', shell=True)

priority = 1000  # Lower first, default is 1000

requires_output = True

More examples of rules, utility functions for rules, app/os-specific helpers.


The Fuck has a few settings parameters which can be changed in $XDG_CONFIG_HOME/thefuck/settings.py ($XDG_CONFIG_HOME defaults to ~/.config):

  • rules – list of enabled rules, by default thefuck.conf.DEFAULT_RULES;
  • exclude_rules – list of disabled rules, by default [];
  • require_confirmation – requires confirmation before running new command, by default True;
  • wait_command – max amount of time in seconds for getting previous command output;
  • no_colors – disable colored output;
  • priority – dict with rules priorities, rule with lower priority will be matched first;
  • debug – enables debug output, by default False;
  • history_limit – numeric value of how many history commands will be scanned, like 2000;
  • alter_history – push fixed command to history, by default True;
  • wait_slow_command – max amount of time in seconds for getting previous command output if it in slow_commands list;
  • slow_commands – list of slow commands.

Example of settings.py:

rules = ['sudo', 'no_command']
exclude_rules = ['git_push']
require_confirmation = True
wait_command = 10
no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
debug = False
history_limit = 9999
wait_slow_command = 20
slow_commands = ['react-native', 'gradle']

Or via environment variables:

  • THEFUCK_RULES – list of enabled rules, like DEFAULT_RULES:rm_root or sudo:no_command;
  • THEFUCK_EXCLUDE_RULES – list of disabled rules, like git_pull:git_push;
  • THEFUCK_REQUIRE_CONFIRMATION – require confirmation before running new command, true/false;
  • THEFUCK_WAIT_COMMAND – max amount of time in seconds for getting previous command output;
  • THEFUCK_NO_COLORS – disable colored output, true/false;
  • THEFUCK_PRIORITY – priority of the rules, like no_command=9999:apt_get=100, rule with lower priority will be matched first;
  • THEFUCK_DEBUG – enables debug output, true/false;
  • THEFUCK_HISTORY_LIMIT – how many history commands will be scanned, like 2000;
  • THEFUCK_ALTER_HISTORY – push fixed command to history true/false;
  • THEFUCK_WAIT_SLOW_COMMAND – max amount of time in seconds for getting previous command output if it in slow_commands list;
  • THEFUCK_SLOW_COMMANDS – list of slow commands, like lein:gradle.

For example:

export THEFUCK_RULES='sudo:no_command'
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'

Third-party packages with rules

If you want to make very specific rules or rules, that you don't want to make public, but share with other people. You can create a special package with name thefuck_contrib_* with following structure:

      *third-party rules*

And thefuck will find all rules from rules module.

Experimental instant mode

By default The Fuck reruns a previous command and that takes time, in instant mode The Fuck logs output with script and just reads the log.

gif with instant mode

At the moment only Python 3 with bash or zsh is supported.

For enabling instant mode you need to add --enable-experimental-instant-mode to alias initialization in your .bashrc, .bash_profile or .zshrc like:

eval $(thefuck --alias --enable-experimental-instant-mode)



License MIT

Project License can be found here.

thefuck open issues Ask a question     (View All Issues)
  • over 3 years "thefuck" typically loads slower that I manually type the command
  • over 3 years Always outputs "No fucks given" on iTerm2 and zsh
  • over 3 years Sudo not working with gem
  • over 3 years Coveralls duplicates PR comments
  • over 3 years No longer works with an alias to β€œgit push”
  • almost 4 years Xonsh
  • almost 4 years zsh command not found with git push
  • almost 4 years fuck has issues with ssh identifier files
  • almost 4 years open with mac on a file the does not exist does not just create the damn file
  • almost 4 years allow for a flag that executes immediately
  • almost 4 years Terminal input fucked after running fuck
  • almost 4 years Not able to install 'the fuck'
  • almost 4 years Command not found
  • almost 4 years When you fuck up using fuck fuck doesn't unfuck your fuck-up
  • almost 4 years version 2.5.6-1: AttributeError: 'NoneType' object has no attribute 'stdout'
  • almost 4 years powershell encoding warning on every 'fuck' execution
  • about 4 years Fix order of arguments to `ln`
  • about 4 years Always corrects to empty git subcommands
  • about 4 years -bash: usage:: command not found
  • about 4 years Receiving "command not found" on configuration
  • about 4 years Archlinux fuck after command not working with zsh
  • about 4 years Cannot associate to 'fuck' self
  • about 4 years white-space safe 'thefuck' with the history line passed as a single arg?
  • about 4 years werid behavior
  • about 4 years pacman is not sudoed after typo
  • about 4 years got commit corrects itself to go commit instead of git commit
  • over 4 years psutil: platform cygwin is not supported (thefuck won't install on Cygwin)
  • over 4 years Change way of interaction with shells
  • over 4 years Deletes temporary session history in bash
  • over 4 years amke becomes rake, not make
thefuck open pull requests (View All Pulls)
  • #N/A Remove fucked up cmd from history regardless of status
  • Added missing psutil dependency for install command
  • adding dnf install rule
  • Delete NULL bytes from command.script_parts[0]
  • Custom fuckups rule -- no command line args
  • custom fuckups with --ifuckedup
  • Update sudo.py
  • Change 'Abort' message to the more appropriate 'Pulled out'
  • Update rm_dir.py
  • Readme fixes
  • #493: Add `put_to_history` back to Fish
  • #N/A Add a new rule `brew_update_formula`
  • Switch from pathlib to pathlib2
  • Add a new rule `git_rebase_no_changes`.
  • Fix functional tests on travis-ci
  • #N/A: Update cargo_no_command rule to support current Cargo
  • start work on -y
  • Run flake8 in Travis, fix some errors
  • Fix issue with scrolling when package not found
  • bash: fix parsing of command substitution
  • README->Installation: Clarify that the alias is really needed
  • Added hebrew the list of keyboard layouts
  • fix $PATH problem when using cmder(git-bash) on windows.
  • Make fish like bash/zsh
  • Test getting status code
  • Added fuck off, per #420
  • Add special error message for 'shit' alias
  • Update README.md
  • [WIP] Add smart_rule and integrate with shell_logger
thefuck questions on Stackoverflow (View All Questions)
  • Error while installing thefuck module
thefuck list of languages used
thefuck latest release notes
  • add support of third-party packages with rules (#737);
  • fix Windows support (#715);
  • fix zsh alias (#733);
  • new rule: heroku_multiple_apps – add --app <app> to heroku commands like heroku pg (#729);
  • new rule: apt_list_upgradable – helps you run apt list --upgradable after apt update (#732);
  • minor bug fixes.
  • instant fuck mode support on macOS (#682);
  • command selection with ctrl+n and ctrl+p instead of and (#711);
  • improvements in cache (#707);
  • fixed exception in python3 + fish (#708);
  • fixed configuration code for fish shell (#658);
  • support parameters in PowerShell (#696);
  • rules api changed, Command.output instead of stdout/stderr (#682, #691);
  • multiline PS1 with instant mode (#692);
  • add php_s rule that replaces -s by -S when trying to run a local php server (#655);
  • add dnf_no_such_command rule that fixes mistyped DNF commands (#698);
  • add git_remote_delete rule that replaces git remote delete remote_name with git remote remove remote_name (#670);
  • add git_push_different_branch_names rule that fixes pushes when local brach name does not match remote branch name (#652);
  • add prove_recursively rule that adds -r when called with directory;
  • add brew_cask_dependency rule that installs cask dependencies;
  • fix brew_update_formula rule (#710).
  • show warning about Python 2 only if Python 2 used (#685)
Other projects in Python