thefuck
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 vimE: 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?
➜ fucksudo apt-get install vim [enter/↑/↓/ctrl+c][sudo] password for nvbn:Reading package lists... Done...
➜ git pushfatal: 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
➜ fuckgit push --set-upstream origin master [enter/↑/↓/ctrl+c]Counting objects: 9, done....
➜ puthonNo command 'puthon' found, did you mean: Command 'python' from package 'python-minimal' (main) Command 'python' from package 'python3' (main)zsh: command not found: puthon
➜ fuckpython [enter/↑/↓/ctrl+c]Python 3.4.2 (default, Oct 8 2014, 13:08:17)...
➜ git brnchgit: 'brnch' is not a git command. See 'git --help'.
Did you mean this? branch
➜ fuckgit branch [enter/↑/↓/ctrl+c]* master
➜ lein rpl'rpl' is not a task. See 'lein help'.
Did you mean this? repl
➜ fucklein repl [enter/↑/↓/ctrl+c]nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848REPL-y 0.3.1...
If you're not afraid of blindly running corrected commands, the
settings option can be disabled:
➜ apt-get install vimE: 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?
➜ fucksudo 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 updatesudo apt install python3-dev python3-pip python3-setuptoolspip3 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 install thefuck
Alternatively, you may use an OS package manager (OS X, Ubuntu, Arch).
#
It is recommended that you place this command in your
,
,
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
(or your shell config file like
).
To run fixed commands without confirmation, use the
option (or just
for short, or
if you're especially frustrated):
fuck --yeah
To fix commands recursively until succeeding, use the
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:
– fixes misspelled commands likeadb_unknown_command
;adb logcta
– addsag_literal
to-Q
when suggested;ag
– fixes misspelled commands likeaws_cli
;aws dynamdb scan
– fixes misspelled commands likeaz_cli
;az providers
– runscargo
instead ofcargo build
;cargo
– fixes wrong commands likecargo_no_command
;cargo buid
– replacescat_dir
withcat
when you try tols
a directory;cat
– spellchecks and corrects failed cd commands;cd_correction
– changescd_cs
tocs
;cd
– creates directories before cd'ing into them;cd_mkdir
– changescd_parent
tocd..
;cd ..
– adds execution bit;chmod_x
– appends common suffixes for chocolatey packages;choco_install
– fixes composer command name;composer_not_command
– fixes conda commands;conda_mistype
– creates a new directory when you attempt tocp_create_destination
orcp
to a non-existent onemv
– addscp_omitting_directory
when you-a
directory;cp
– adds missingcpp11
to-std=c++11
org++
;clang++
– fixesdirty_untar
command that untarred in the current directory;tar x
– fixesdirty_unzip
command that unzipped in the current directory;unzip
– addsdjango_south_ghost
to failed because ghosts django south migration;--delete-ghost-migrations
– addsdjango_south_merge
to inconsistent django south migration;--merge
– executes adocker_login
and repeats the previous command;docker login
– fixes wrong docker commands likedocker_not_command
;docker tags
‐ removes the container that is using the image before removing the image;docker_image_being_used_by_container
– fixes repetitions likedry
;git git push
– fixes misspelled fabric commands;fab_command_not_found
– replaces Alt+Space with Space character;fix_alt_space
– opens a file with an error in yourfix_file
;$EDITOR
– fixes wronggem_unknown_command
commands;gem
– fixes "pathspec 'foo' did not match any file(s) known to git.";git_add
– addsgit_add_force
to--force
when paths are .gitignore'd;git add <pathspec>...
– fixesgit_bisect_usage
,git bisect strt
,git bisect goood
, etc. when bisecting;git bisect rset
– changesgit_branch_delete
togit branch -d
;git branch -D
– changesgit_branch_delete_checked_out
togit branch -d
when trying to delete a checked out branch;git checkout master && git branch -D
– offersgit_branch_exists
,git branch -d foo
orgit branch -D foo
when creating a branch that already exists;git checkout foo
– catchesgit_branch_list
in place ofgit branch list
and removes created branch;git branch
– fixes commands such asgit_branch_0flag
andgit branch 0v
removing the created branch;git branch 0r
– fixes branch name or creates new branch;git_checkout
– replacesgit_clone_git_clone
withgit clone git clone ...git clone ...
– addsgit_clone_missing
to URLs that appear to link to a git repository.git clone
– offersgit_commit_add
orgit commit -a ...
after previous commit if it failed because nothing was staged;git commit -p ...
– offersgit_commit_amend
after previous commit;git commit --amend
– offersgit_commit_reset
after previous commit;git reset HEAD~
– addsgit_diff_no_index
to previous--no-index
on untracked files;git diff
– addsgit_diff_staged
to previous--staged
with unexpected output;git diff
– fixesgit_fix_stash
commands (misspelled subcommand and missinggit stash
);save
– fixesgit_flag_after_filenamefatal: bad flag '...' after filename
– fixesgit_help_aliased
commands replacing with the aliased command;git help <alias>
– addsgit_hook_bypass
flag previous to--no-verify
,git am
, orgit commit
command;git push
– fixes mistypedgit_lfs_mistype
commands;git lfs <command>
– fixes incorrect branch name betweengit_main_master
andmainmaster
– adds remote to branch names;git_merge
– addsgit_merge_unrelated
when required--allow-unrelated-histories
– fixes wrong git commands likegit_not_command
;git brnch
– sets upstream before executing previousgit_pull
;git pull
– clones instead of pulling when the repo does not exist;git_pull_clone
– stashes changes before pulling and pops them afterwards;git_pull_uncommitted_changes
– addsgit_push
to previous failed--set-upstream origin $branch
;git push
– fixes pushes when local branch name does not match remote branch name;git_push_different_branch_names
– runsgit_push_pull
whengit pull
was rejected;push
– creates an initial commit if you forget and onlygit_push_without_commits
, when setting up a new project;git add .
– runsgit_rebase_no_changes
instead ofgit rebase --skip
when there are no changes;git rebase --continue
– replacesgit_remote_delete
withgit remote delete remote_name
;git remote remove remote_name
– addsgit_rm_local_modifications
or-f
when you try to--cached
a locally modified file;rm
– addsgit_rm_recursive
when you try to-r
a directory;rm
– addsgit_rm_staged
or-f
when you try to--cached
a file with staged changesrm
– offersgit_rebase_merge_dir
or removing thegit rebase (--continue | --abort | --skip)
dir when a rebase is in progress;.git/rebase-merge
– runsgit_remote_seturl_add
whengit remote add
on nonexistent remote;git remote set_url
– stashes your local modifications before rebasing or switching branch;git_stash
– adds your local modifications before popping stash, then resets;git_stash_pop
– addsgit_tag_force
to--force
when the tag already exists;git tag <tagname>
– adds a missing dash to commands likegit_two_dashes
orgit commit -amend
;git rebase -continue
– appendsgo_run
extension when compiling/running Go programs;.go
– fixes wronggo_unknown_command
commands, for examplego
;go bulid
– fixes not found or ambiguousgradle_no_task
task;gradle
– replacesgradle_wrapper
withgradle
;./gradlew
– fixesgrep_arguments_order
arguments order for situations likegrep
;grep -lir . test
– addsgrep_recursive
when you try to-r
directory;grep
– fixes misspelledgrunt_task_not_found
commands;grunt
– fixes misspelledgulp_not_task
tasks;gulp
– prependshas_exists_script
when script/binary exists;./
– addsheroku_multiple_apps
to--app <app>
commands likeheroku
;heroku pg
– fixes wrongheroku_not_command
commands likeheroku
;heroku log
– tries to replace command with the most similar command from history;history
– tries to fixhostscli
usage;hostscli
– fixes wrong device names likeifconfig_device_not_found
towlan0
;wlp2s0
– removesjava
extension when running Java programs;.java
– appends missingjavac
when compiling Java files;.java
– fixes wronglein_not_task
tasks likelein
;lein rpl
– changeslong_form_help
to-h
when the short form version is not supported--help
– catches hard link creation on directories, suggest symbolic link;ln_no_hard_link
– fixesln_s_order
arguments order;ln -s
– addsls_all
to-A
when output is empty;ls
– addsls_lah
to-lah
;ls
– changes manual section;man
– fixes man commands without spaces, for exampleman_no_space
;mandiff
– fixes wrongmercurial
commands;hg
– fixes command with missing space likemissing_space_before_subcommand
;npminstall
– addsmkdir_p
when you try to create a directory without a parent;-p
– addsmvn_no_command
toclean package
;mvn
– fixes misspelled life cycle phases withmvn_unknown_lifecycle_phase
;mvn
– fixesnpm_missing_script
custom script name innpm
;npm run-script <script>
– adds missingnpm_run_script
for customrun-script
scripts;npm
– fixes wrong npm commands likenpm_wrong_command
;npm urgrade
– fixes wrong console commands, for exampleno_command
;vom/vim
– creates missing directories withno_such_file
andmv
commands;cp
– fixes wrong commands foromnienv_no_such_command
,goenv
,nodenv
andpyenv
(eg.:rbenv
orpyenv isntall
);goenv list
– either prependsopen
to address passed tohttp://
or creates a new file or directory and passes it toopen
;open
– fixes permission issues withpip_install
commands by addingpip install
or prepending--user
if necessary;sudo
– fixes wrongpip_unknown_command
commands, for examplepip
;pip instatl/pip install
– replacesphp_s
by-s
when trying to run a local php server;-S
– kills process that bound port;port_already_in_use
– addsprove_recursively
when called with directory;-r
– prependspython_command
when you try to run non-executable/withoutpython
python script;./
– appends missingpython_execute
when executing Python files;.py
– fixes ModuleNotFoundError by trying topython_module_error
that module;pip install
– fixes uneven usage ofquotation_marks
and'
when containing args';"
– replaces not found path with a similar absolute path from history;path_from_history
– runs pending migrations;rails_migrations_pending
– fixes unrecognizedreact_native_command_unrecognized
commands;react-native
– removes leading shell prompt symbolremove_shell_prompt_literal
, common when copying commands from documentations;$
– removes trailing cedillasremove_trailing_cedilla
, a common typo for European keyboard layouts;ç
– addsrm_dir
when you try to remove a directory;-rf
– corrects wrong scm likescm_correction
tohg log
;git log
– adds missing '/' tosed_unterminated_s
'ssed
commands;s
– changessl_ls
tosl
;ls
– removes host fromssh_known_hosts
on warning;known_hosts
– prependssudo
to the previous command if it failed because of permissions;sudo
– runs commands from userssudo_command_from_user_path
with$PATH
;sudo
– switches command from your local layout to en;switch_lang
– correctly orders parameters of confusingsystemctl
;systemctl
– runsterraform_init.py
before plan or apply;terraform init
– fixes unrecognizedterraform_no_command.py
commands;terraform
– runstest.py
instead ofpytest
;test.py
– creates missing directories before "touching";touch
– runstsuru_login
if not authenticated or session expired;tsuru login
– fixes wrongtsuru_not_command
commands liketsuru
;tsuru shell
– fixestmux
commands;tmux
– fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command onunknown_command
;hdfs dfs ls
– removesunsudo
from previous command if a process refuses to run on superuser privilege.sudo
– starts up the vagrant instance;vagrant_up
– fixeswhois
command;whois
– fixesworkon_doesnt_exists
env name os suggests to create new.virtualenvwrapper
– removes an improperly placed hyphen (wrong_hyphen_before_subcommand
->apt-install
,apt install
->git-log
, etc.)git log
– fixes aliasedyarn_alias
commands likeyarn
;yarn ls
– fixes misspelledyarn_command_not_found
commands;yarn
– fixes replacedyarn_command_replaced
commands;yarn
– makes it easier to openyarn_help
documentation;yarn
Back to Contents
The following rules are enabled by default on specific platforms only:
– installs app from apt if it not installed (requiresapt_get
/python-commandnotfound
);python3-commandnotfound
– changes trying to search usingapt_get_search
with searching usingapt-get
;apt-cache
– fixes invalidapt_invalid_operation
andapt
calls, likeapt-get
;apt-get isntall vim
– helps you runapt_list_upgradable
afterapt list --upgradable
;apt update
– helps you runapt_upgrade
afterapt upgrade
;apt list --upgradable
– installs cask dependencies;brew_cask_dependency
– fixes formula name forbrew_install
;brew install
– turnsbrew_reinstall
intobrew install <formula>
;brew reinstall <formula>
– addsbrew_link
if linking fails;--overwrite --dry-run
– addsbrew_uninstall
to--force
if multiple versions were installed;brew uninstall
– fixes wrong brew commands, for examplebrew_unknown_command
;brew docto/brew doctor
– turnsbrew_update_formula
intobrew update <formula>
;brew upgrade <formula>
– fixes mistyped DNF commands;dnf_no_such_command
– installs apps on NixOS;nixos_cmd_not_found
– installs app withpacman
if it is not installed (usespacman
,yay
orpikaur
if available);yaourt
– replaces lowercasepacman_invalid_option
options with uppercase.pacman
– fixes package name withpacman_not_found
,pacman
,yay
orpikaur
.yaourt
– fixes invalidyum_invalid_operation
calls, likeyum
;yum isntall vim
The following commands are bundled with The Fuck, but are not enabled by default:
– addsgit_push_force
to a--force-with-lease
(may conflict withgit push
);git_push_pull
– addsrm_root
to--no-preserve-root
command.rm -rf /
Back to Contents
Creating your own rules
To add your own rule, create a file named
in
. The rule file must contain two functions:
match(command: Command) -> boolget_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
,
and
.
has three attributes:
,
and
.
Your rule should not change
.
Rules api changed in 3.0: To access a rule's settings, import it with
is a special object assembled from
,
and values from env (see more below).
A simple example rule for running a script with
:
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
(
defaults to
):
– list of enabled rules, by defaultrules
;thefuck.const.DEFAULT_RULES
– list of disabled rules, by defaultexclude_rules
;[]
– requires confirmation before running new command, by defaultrequire_confirmation
;True
– the max amount of time in seconds for getting previous command output;wait_command
– disable colored output;no_colors
– dict with rules priorities, rule with lowerpriority
will be matched first;priority
– enables debug output, by defaultdebug
;False
– the numeric value of how many history commands will be scanned, likehistory_limit
;2000
– push fixed command to history, by defaultalter_history
;True
– max amount of time in seconds for getting previous command output if it inwait_slow_command
list;slow_commands
– list of slow commands;slow_commands
– the maximum number of close matches to suggest, by defaultnum_close_matches
.3
– path prefixes to ignore when searching for commands, by defaultexcluded_search_path_prefixes
.[]
An example of
:
rules = ['sudo', 'no_command']exclude_rules = ['git_push']require_confirmation = Truewait_command = 10no_colors = Falsepriority = {'sudo': 100, 'no_command': 9999}debug = Falsehistory_limit = 9999wait_slow_command = 20slow_commands = ['react-native', 'gradle']num_close_matches = 5
Or via environment variables:
– list of enabled rules, likeTHEFUCK_RULES
orDEFAULT_RULES:rm_root
;sudo:no_command
– list of disabled rules, likeTHEFUCK_EXCLUDE_RULES
;git_pull:git_push
– require confirmation before running new command,THEFUCK_REQUIRE_CONFIRMATION
;true/false
– the max amount of time in seconds for getting previous command output;THEFUCK_WAIT_COMMAND
– disable colored output,THEFUCK_NO_COLORS
;true/false
– priority of the rules, likeTHEFUCK_PRIORITY
, rule with lowerno_command=9999:apt_get=100
will be matched first;priority
– enables debug output,THEFUCK_DEBUG
;true/false
– how many history commands will be scanned, likeTHEFUCK_HISTORY_LIMIT
;2000
– push fixed command to historyTHEFUCK_ALTER_HISTORY
;true/false
– the max amount of time in seconds for getting previous command output if it inTHEFUCK_WAIT_SLOW_COMMAND
list;slow_commands
– list of slow commands, likeTHEFUCK_SLOW_COMMANDS
;lein:gradle
– the maximum number of close matches to suggest, likeTHEFUCK_NUM_CLOSE_MATCHES
.5
– path prefixes to ignore when searching for commands, by defaultTHEFUCK_EXCLUDED_SEARCH_PATH_PREFIXES
.[]
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=10export 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
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
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
to the alias initialization in
,
or
.
For example:
eval $(thefuck --alias --enable-experimental-instant-mode)
Back to Contents
Developing
See CONTRIBUTING.md
License MIT
Project License can be found here.