The Fuck

The Fuck is a magnificent app, inspired by a @liamosaur tweet, that corrects errors in previous console commands.
Is The Fuck too slow? Try the experimental instant mode!
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?
โ fuck
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
โ fuck
git push --set-upstream origin master [enter/โ/โ/ctrl+c]
Counting objects: 9, done.
...
โ puthon
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
โ fuck
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?
branch
โ fuck
git branch [enter/โ/โ/ctrl+c]
* master
โ lein rpl
'rpl' is not a task. See 'lein help'.
Did you mean this?
repl
โ fuck
lein repl [enter/โ/โ/ctrl+c]
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
REPL-y 0.3.1
...
If you're not afraid of blindly running corrected commands, the
require_confirmation settings option can be disabled:
โ 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?
โ fuck
sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...
Contents
- Requirements
- Installations
- Updating
- How it works
- Creating your own rules
- Settings
- Third party packages with rules
- Experimental instant mode
- Developing
- License
Requirements
- python (3.5+)
- pip
- python-dev
Back to Contents
Installation
On macOS or Linux, you can install The Fuck via Homebrew:
brew install thefuck
On Ubuntu / Mint, install The Fuck with the following commands:
sudo apt update
sudo apt install python3-dev python3-pip python3-setuptools
pip3 install thefuck --user
On FreeBSD, install The Fuck with the following commands:
pkg install thefuck
On ChromeOS, install The Fuck using chromebrew with the following command:
crew install thefuck
On Arch based systems, install The Fuck with the following command:
sudo pacman -S thefuck
On other systems, install The Fuck by using pip:
pip install thefuck
Alternatively, you may use an OS package manager (OS X, Ubuntu, Arch).
#
It is recommended that you 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 are only available in a new shell session. To make changes immediately
available, run source ~/.bashrc (or your shell config file like .zshrc).
To run fixed commands without confirmation, use the --yeah option (or just -y for short, or --hard if you're especially frustrated):
fuck --yeah
To fix commands recursively until succeeding, use the -r option:
fuck -r
Back to Contents
Updating
pip3 install thefuck --upgrade
Note: Alias functionality was changed in v1.34 of The Fuck
Uninstall
To remove The Fuck, reverse the installation process:
- erase or comment thefuck alias line from your Bash, Zsh, Fish, Powershell, tcsh, ... shell config
- use your package manager (brew, pip3, pkg, crew, pip) to uninstall the binaries
How it works
The Fuck attempts to match the previous command with a rule. If a match is found, a new command is created using the matched rule and executed. The following rules are enabled by default:
adb_unknown_commandโ fixes misspelled commands likeadb logcta;ag_literalโ adds-Qtoagwhen suggested;aws_cliโ fixes misspelled commands likeaws dynamdb scan;az_cliโ fixes misspelled commands likeaz providers;cargoโ runscargo buildinstead ofcargo;cargo_no_commandโ fixes wrong commands likecargo buid;cat_dirโ replacescatwithlswhen you try tocata directory;cd_correctionโ spellchecks and corrects failed cd commands;cd_csโ changescstocd;cd_mkdirโ creates directories before cd'ing into them;cd_parentโ changescd..tocd ..;chmod_xโ adds execution bit;choco_installโ appends common suffixes for chocolatey packages;composer_not_commandโ fixes composer command name;conda_mistypeโ fixes conda commands;cp_create_destinationโ creates a new directory when you attempt tocpormvto a non-existent onecp_omitting_directoryโ adds-awhen youcpdirectory;cpp11โ adds missing-std=c++11tog++orclang++;dirty_untarโ fixestar xcommand that untarred in the current directory;dirty_unzipโ fixesunzipcommand that unzipped in the current directory;django_south_ghostโ adds--delete-ghost-migrationsto failed because ghosts django south migration;django_south_mergeโ adds--mergeto inconsistent django south migration;docker_loginโ executes adocker loginand repeats the previous command;docker_not_commandโ fixes wrong docker commands likedocker tags;docker_image_being_used_by_containerโ removes the container that is using the image before removing the image;dryโ fixes repetitions likegit git push;fab_command_not_foundโ fixes 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 wronggemcommands;git_addโ fixes "pathspec 'foo' did not match any file(s) known to git.";git_add_forceโ adds--forcetogit add <pathspec>...when paths are .gitignore'd;git_bisect_usageโ fixesgit bisect strt,git bisect goood,git bisect rset, etc. when bisecting;git_branch_deleteโ changesgit branch -dtogit branch -D;git_branch_delete_checked_outโ changesgit branch -dtogit checkout master && git branch -Dwhen trying to delete a checked out branch;git_branch_existsโ offersgit branch -d foo,git branch -D fooorgit checkout foowhen creating a branch that already exists;git_branch_listโ catchesgit branch listin place ofgit branchand removes created branch;git_branch_0flagโ fixes commands such asgit branch 0vandgit branch 0rremoving the created branch;git_checkoutโ fixes branch name or creates new branch;git_clone_git_cloneโ replacesgit clone git clone ...withgit clone ...git_clone_missingโ addsgit cloneto URLs that appear to link to a git repository.git_commit_addโ offersgit commit -a ...orgit commit -p ...after previous commit if it failed because nothing was staged;git_commit_amendโ offersgit commit --amendafter previous commit;git_commit_resetโ offersgit reset HEAD~after previous commit;git_diff_no_indexโ adds--no-indexto previousgit diffon untracked files;git_diff_stagedโ adds--stagedto previousgit diffwith unexpected output;git_fix_stashโ fixesgit stashcommands (misspelled subcommand and missingsave);git_flag_after_filenameโ fixesfatal: bad flag '...' after filenamegit_help_aliasedโ fixesgit help <alias>commands replacing with the aliased command;git_hook_bypassโ adds--no-verifyflag previous togit am,git commit, orgit pushcommand;git_lfs_mistypeโ fixes mistypedgit lfs <command>commands;git_main_masterโ fixes incorrect branch name betweenmainandmastergit_mergeโ adds remote to branch names;git_merge_unrelatedโ adds--allow-unrelated-historieswhen requiredgit_not_commandโ fixes wrong git commands likegit brnch;git_pullโ sets upstream before executing previousgit 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 $branchto previous failedgit push;git_push_different_branch_namesโ fixes pushes when local branch name does not match remote branch name;git_push_pullโ runsgit pullwhenpushwas rejected;git_push_without_commitsโ creates an initial commit if you forget and onlygit add ., when setting up a new project;git_rebase_no_changesโ runsgit rebase --skipinstead ofgit rebase --continuewhen there are no changes;git_remote_deleteโ replacesgit remote delete remote_namewithgit remote remove remote_name;git_rm_local_modificationsโ adds-for--cachedwhen you try torma locally modified file;git_rm_recursiveโ adds-rwhen you try torma directory;git_rm_stagedโ adds-for--cachedwhen you try torma file with staged changesgit_rebase_merge_dirโ offersgit rebase (--continue | --abort | --skip)or removing the.git/rebase-mergedir when a rebase is in progress;git_remote_seturl_addโ runsgit remote addwhengit remote set_urlon nonexistent 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--forcetogit tag <tagname>when the tag already exists;git_two_dashesโ adds a missing dash to commands likegit commit -amendorgit rebase -continue;go_runโ appends.goextension when compiling/running Go programs;go_unknown_commandโ fixes wronggocommands, for examplego bulid;gradle_no_taskโ fixes not found or ambiguousgradletask;gradle_wrapperโ replacesgradlewith./gradlew;grep_arguments_orderโ fixesgreparguments order for situations likegrep -lir . test;grep_recursiveโ adds-rwhen you try togrepdirectory;grunt_task_not_foundโ fixes misspelledgruntcommands;gulp_not_taskโ fixes misspelledgulptasks;has_exists_scriptโ prepends./when script/binary exists;heroku_multiple_appsโ adds--app <app>toherokucommands likeheroku pg;heroku_not_commandโ fixes wrongherokucommands likeheroku log;historyโ tries to replace command with the most similar command from history;hostscliโ tries to fixhostscliusage;ifconfig_device_not_foundโ fixes wrong device names likewlan0towlp2s0;javaโ removes.javaextension when running Java programs;javacโ appends missing.javawhen compiling Java files;lein_not_taskโ fixes wrongleintasks likelein rpl;long_form_helpโ changes-hto--helpwhen the short form version is not supportedln_no_hard_linkโ catches hard link creation on directories, suggest symbolic link;ln_s_orderโ fixesln -sarguments order;ls_allโ adds-Atolswhen output is empty;ls_lahโ adds-lahtols;manโ changes manual section;man_no_spaceโ fixes man commands without spaces, for examplemandiff;mercurialโ fixes wronghgcommands;missing_space_before_subcommandโ fixes command with missing space likenpminstall;mkdir_pโ adds-pwhen you try to create a directory without a parent;mvn_no_commandโ addsclean packagetomvn;mvn_unknown_lifecycle_phaseโ fixes misspelled life cycle phases withmvn;npm_missing_scriptโ fixesnpmcustom script name innpm run-script <script>;npm_run_scriptโ adds missingrun-scriptfor customnpmscripts;npm_wrong_commandโ fixes wrong npm commands likenpm urgrade;no_commandโ fixes wrong console commands, for examplevom/vim;no_such_fileโ creates missing directories withmvandcpcommands;omnienv_no_such_commandโ fixes wrong commands forgoenv,nodenv,pyenvandrbenv(eg.:pyenv isntallorgoenv list);openโ either prependshttp://to address passed toopenor creates a new file or directory and passes it toopen;pip_installโ fixes permission issues withpip installcommands by adding--useror prependingsudoif necessary;pip_unknown_commandโ fixes wrongpipcommands, for examplepip instatl/pip install;php_sโ replaces-sby-Swhen trying to run a local php server;port_already_in_useโ kills process that bound port;prove_recursivelyโ adds-rwhen called with directory;python_commandโ prependspythonwhen you try to run non-executable/without./python script;python_executeโ appends missing.pywhen executing Python files;python_module_errorโ fixes ModuleNotFoundError by trying topip installthat module;quotation_marksโ fixes uneven usage of'and"when containing args';path_from_historyโ replaces not found path with a similar absolute path from history;rails_migrations_pendingโ runs pending migrations;react_native_command_unrecognizedโ fixes unrecognizedreact-nativecommands;remove_shell_prompt_literalโ removes leading shell prompt symbol$, common when copying commands from documentations;remove_trailing_cedillaโ removes trailing cedillasรง, a common typo for European keyboard layouts;rm_dirโ adds-rfwhen you try to remove a directory;scm_correctionโ corrects wrong scm likehg logtogit log;sed_unterminated_sโ adds missing '/' tosed'sscommands;sl_lsโ changessltols;ssh_known_hostsโ removes host fromknown_hostson warning;sudoโ prependssudoto the previous command if it failed because of permissions;sudo_command_from_user_pathโ runs commands from users$PATHwithsudo;switch_langโ switches command from your local layout to en;systemctlโ correctly orders parameters of confusingsystemctl;terraform_init.pyโ runsterraform initbefore plan or apply;terraform_no_command.pyโ fixes unrecognizedterraformcommands;test.pyโ runspytestinstead oftest.py;touchโ creates missing directories before "touching";tsuru_loginโ runstsuru loginif not authenticated or session expired;tsuru_not_commandโ fixes wrongtsurucommands liketsuru shell;tmuxโ fixestmuxcommands;unknown_commandโ fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command onhdfs dfs ls;unsudoโ removessudofrom previous command if a process refuses to run on superuser privilege.vagrant_upโ starts up the vagrant instance;whoisโ fixeswhoiscommand;workon_doesnt_existsโ fixesvirtualenvwrapperenv name os suggests to create new.wrong_hyphen_before_subcommandโ removes an improperly placed hyphen (apt-install->apt install,git-log->git log, etc.)yarn_aliasโ fixes aliasedyarncommands likeyarn ls;yarn_command_not_foundโ fixes misspelledyarncommands;yarn_command_replacedโ fixes replacedyarncommands;yarn_helpโ makes it easier to openyarndocumentation;
Back to Contents
The following rules are enabled by default on specific platforms only:
apt_getโ installs app from apt if it not installed (requirespython-commandnotfound/python3-commandnotfound);apt_get_searchโ changes trying to search usingapt-getwith searching usingapt-cache;apt_invalid_operationโ fixes invalidaptandapt-getcalls, likeapt-get isntall vim;apt_list_upgradableโ helps you runapt list --upgradableafterapt update;apt_upgradeโ helps you runapt upgradeafterapt list --upgradable;brew_cask_dependencyโ installs cask dependencies;brew_installโ fixes formula name forbrew install;brew_reinstallโ turnsbrew install <formula>intobrew reinstall <formula>;brew_linkโ adds--overwrite --dry-runif linking fails;brew_uninstallโ adds--forcetobrew uninstallif multiple versions were installed;brew_unknown_commandโ fixes wrong brew commands, for examplebrew docto/brew doctor;brew_update_formulaโ turnsbrew update <formula>intobrew upgrade <formula>;dnf_no_such_commandโ fixes mistyped DNF commands;nixos_cmd_not_foundโ installs apps on NixOS;pacmanโ installs app withpacmanif it is not installed (usesyay,pikauroryaourtif available);pacman_invalid_optionโ replaces lowercasepacmanoptions with uppercase.pacman_not_foundโ fixes package name withpacman,yay,pikauroryaourt.yum_invalid_operationโ fixes invalidyumcalls, likeyum isntall vim;
The following commands are bundled with The Fuck, but are not enabled by default:
git_push_forceโ adds--force-with-leaseto agit push(may conflict withgit_push_pull);rm_rootโ adds--no-preserve-roottorm -rf /command.
Back to Contents
Creating your own rules
To add your own rule, create a file named your-rule-name.py
in ~/.config/thefuck/rules. The rule file must contain two functions:
match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
Additionally, rules can contain optional functions:
side_effect(old_command: Command, fixed_command: str) -> None
Rules can also contain the optional variables enabled_by_default, requires_output and priority.
Command has three attributes: script, output and script_parts.
Your rule should not change Command.
Rules api changed in 3.0: To access a rule's settings, import it with
from thefuck.conf import settings
settings is a special object assembled from ~/.config/thefuck/settings.py,
and values from env (see more below).
A simple example rule for running a 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.
Back to Contents
Settings
Several The Fuck parameters can be changed in the file $XDG_CONFIG_HOME/thefuck/settings.py
($XDG_CONFIG_HOME defaults to ~/.config):
rulesโ list of enabled rules, by defaultthefuck.const.DEFAULT_RULES;exclude_rulesโ list of disabled rules, by default[];require_confirmationโ requires confirmation before running new command, by defaultTrue;wait_commandโ the max amount of time in seconds for getting previous command output;no_colorsโ disable colored output;priorityโ dict with rules priorities, rule with lowerprioritywill be matched first;debugโ enables debug output, by defaultFalse;history_limitโ the numeric value of how many history commands will be scanned, like2000;alter_historyโ push fixed command to history, by defaultTrue;wait_slow_commandโ max amount of time in seconds for getting previous command output if it inslow_commandslist;slow_commandsโ list of slow commands;num_close_matchesโ the maximum number of close matches to suggest, by default3.excluded_search_path_prefixesโ path prefixes to ignore when searching for commands, by default[].
An 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']
num_close_matches = 5
Or via environment variables:
THEFUCK_RULESโ list of enabled rules, likeDEFAULT_RULES:rm_rootorsudo:no_command;THEFUCK_EXCLUDE_RULESโ list of disabled rules, likegit_pull:git_push;THEFUCK_REQUIRE_CONFIRMATIONโ require confirmation before running new command,true/false;THEFUCK_WAIT_COMMANDโ the 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, likeno_command=9999:apt_get=100, rule with lowerprioritywill be matched first;THEFUCK_DEBUGโ enables debug output,true/false;THEFUCK_HISTORY_LIMITโ how many history commands will be scanned, like2000;THEFUCK_ALTER_HISTORYโ push fixed command to historytrue/false;THEFUCK_WAIT_SLOW_COMMANDโ the max amount of time in seconds for getting previous command output if it inslow_commandslist;THEFUCK_SLOW_COMMANDSโ list of slow commands, likelein:gradle;THEFUCK_NUM_CLOSE_MATCHESโ the maximum number of close matches to suggest, like5.THEFUCK_EXCLUDED_SEARCH_PATH_PREFIXESโ path prefixes to ignore when searching for commands, by default[].
For example:
export THEFUCK_RULES='sudo:no_command'
export THEFUCK_EXCLUDE_RULES='git_pull:git_push'
export THEFUCK_REQUIRE_CONFIRMATION='true'
export THEFUCK_WAIT_COMMAND=10
export THEFUCK_NO_COLORS='false'
export THEFUCK_PRIORITY='no_command=9999:apt_get=100'
export THEFUCK_HISTORY_LIMIT='2000'
export THEFUCK_NUM_CLOSE_MATCHES='5'
Back to Contents
Third-party packages with rules
If you'd like to make a specific set of non-public rules, but would still like
to share them with others, create a package named thefuck_contrib_* with
the following structure:
thefuck_contrib_foo
thefuck_contrib_foo
rules
__init__.py
*third-party rules*
__init__.py
*third-party-utils*
setup.py
The Fuck will find rules located in the rules module.
Back to Contents
Experimental instant mode
The default behavior of The Fuck requires time to re-run previous commands. When in instant mode, The Fuck saves time by logging output with script, then reading the log.
Currently, instant mode only supports Python 3 with bash or zsh. zsh's autocorrect function also needs to be disabled in order for thefuck to work properly.
To enable instant mode, add --enable-experimental-instant-mode
to the alias initialization in .bashrc, .bash_profile or .zshrc.
For example:
eval $(thefuck --alias --enable-experimental-instant-mode)
Back to Contents
Developing
See CONTRIBUTING.md
License MIT
Project License can be found here.

