thefuck: Slow rule eval on WSL

The output of thefuck --version (something like The Fuck 3.1 using Python 3.5.0 and Bash 4.4.12(1)-release):

% thefuck --version
The Fuck 3.29 using Python 3.8.1 and ZSH 5.4.2

Your system (Debian 7, ArchLinux, Windows, etc.):

% uname -r
4.19.84-microsoft-standard

image

How to reproduce the bug:

# linuxbrew using latest.
% brew install -v thefuck
% echo 'eval $(thefuck --alias fuck)' >> ~/.zshrc
% source ~/.zshrc

# some repo
% gitstatus
zsh: command not found: gitstatus

# this takes like 30 seconds.
% fuck

The output of The Fuck with THEFUCK_DEBUG=true exported (typically execute export THEFUCK_DEBUG=true in your shell before The Fuck):

 % fuck --debug
DEBUG: Run with settings: {'alter_history': True,
 'debug': True,
 'env': {'GIT_TRACE': '1', 'LANG': 'C', 'LC_ALL': 'C'},
 'exclude_rules': [],
 'history_limit': None,
 'instant_mode': True,
 'no_colors': False,
 'num_close_matches': 3,
 'priority': {},
 'repeat': False,
 'require_confirmation': True,
 'rules': [<const: All rules enabled>],
 'slow_commands': ['lein', 'react-native', 'gradle', './gradlew', 'vagrant'],
 'user_dir': PosixPath('/c/Users/MikeLloyd/.config/thefuck'),
 'wait_command': 3,
 'wait_slow_command': 15}
[WARN] PS1 doesn't contain user command mark, please ensure that PS1 is not changed after The Fuck alias initialization
DEBUG: Importing rule: adb_unknown_command; took: 0:00:00.000184
DEBUG: Importing rule: ag_literal; took: 0:00:00.000366
DEBUG: Importing rule: apt_get; took: 0:00:00.001400
DEBUG: Importing rule: apt_get_search; took: 0:00:00.000299
DEBUG: Importing rule: apt_invalid_operation; took: 0:00:00.000714
DEBUG: Importing rule: apt_list_upgradable; took: 0:00:00.000370
DEBUG: Importing rule: apt_upgrade; took: 0:00:00.000391
DEBUG: Importing rule: aws_cli; took: 0:00:00.000239
DEBUG: Importing rule: az_cli; took: 0:00:00.000561
DEBUG: Importing rule: brew_cask_dependency; took: 0:00:00.000493
DEBUG: Importing rule: brew_install; took: 0:00:00.000110
DEBUG: Importing rule: brew_link; took: 0:00:00.000261
DEBUG: Importing rule: brew_reinstall; took: 0:00:00.000484
DEBUG: Importing rule: brew_uninstall; took: 0:00:00.000239
DEBUG: Importing rule: brew_unknown_command; took: 0:00:00.000131
DEBUG: Importing rule: brew_update_formula; took: 0:00:00.000234
DEBUG: Importing rule: cargo; took: 0:00:00.000087
DEBUG: Importing rule: cargo_no_command; took: 0:00:00.000237
DEBUG: Importing rule: cat_dir; took: 0:00:00.000262
DEBUG: Importing rule: cd_correction; took: 0:00:00.001040
DEBUG: Importing rule: cd_mkdir; took: 0:00:00.000368
DEBUG: Importing rule: cd_parent; took: 0:00:00.000089
DEBUG: Importing rule: chmod_x; took: 0:00:00.000093
DEBUG: Importing rule: composer_not_command; took: 0:00:00.000252
DEBUG: Importing rule: cp_omitting_directory; took: 0:00:00.000365
DEBUG: Importing rule: cpp11; took: 0:00:00.000296
DEBUG: Importing rule: dirty_untar; took: 0:00:00.000876
DEBUG: Importing rule: dirty_unzip; took: 0:00:00.001614
DEBUG: Importing rule: django_south_ghost; took: 0:00:00.000222
DEBUG: Importing rule: django_south_merge; took: 0:00:00.000233
DEBUG: Importing rule: dnf_no_such_command; took: 0:00:00.085171
DEBUG: Importing rule: docker_login; took: 0:00:00.000305
DEBUG: Importing rule: docker_not_command; took: 0:00:00.083238
DEBUG: Importing rule: dry; took: 0:00:00.000133
DEBUG: Importing rule: fab_command_not_found; took: 0:00:00.000454
DEBUG: Importing rule: fix_alt_space; took: 0:00:00.000304
DEBUG: Importing rule: fix_file; took: 0:00:00.001708
DEBUG: Importing rule: gem_unknown_command; took: 0:00:00.013975
DEBUG: Importing rule: git_add; took: 0:00:00.000560
DEBUG: Importing rule: git_add_force; took: 0:00:00.000243
DEBUG: Importing rule: git_bisect_usage; took: 0:00:00.000315
DEBUG: Importing rule: git_branch_delete; took: 0:00:00.000273
DEBUG: Importing rule: git_branch_exists; took: 0:00:00.000307
DEBUG: Importing rule: git_branch_list; took: 0:00:00.000250
DEBUG: Importing rule: git_checkout; took: 0:00:00.000249
DEBUG: Importing rule: git_commit_amend; took: 0:00:00.000231
DEBUG: Importing rule: git_commit_reset; took: 0:00:00.000262
DEBUG: Importing rule: git_diff_no_index; took: 0:00:00.000296
DEBUG: Importing rule: git_diff_staged; took: 0:00:00.000367
DEBUG: Importing rule: git_fix_stash; took: 0:00:00.000320
DEBUG: Importing rule: git_flag_after_filename; took: 0:00:00.000329
DEBUG: Importing rule: git_help_aliased; took: 0:00:00.000309
DEBUG: Importing rule: git_merge; took: 0:00:00.000267
DEBUG: Importing rule: git_merge_unrelated; took: 0:00:00.000251
DEBUG: Importing rule: git_not_command; took: 0:00:00.000336
DEBUG: Importing rule: git_pull; took: 0:00:00.000260
DEBUG: Importing rule: git_pull_clone; took: 0:00:00.000250
DEBUG: Importing rule: git_pull_uncommitted_changes; took: 0:00:00.000264
DEBUG: Importing rule: git_push; took: 0:00:00.000240
DEBUG: Importing rule: git_push_different_branch_names; took: 0:00:00.000227
DEBUG: Importing rule: git_push_force; took: 0:00:00.000231
DEBUG: Importing rule: git_push_pull; took: 0:00:00.000270
DEBUG: Importing rule: git_push_without_commits; took: 0:00:00.000288
DEBUG: Importing rule: git_rebase_merge_dir; took: 0:00:00.000249
DEBUG: Importing rule: git_rebase_no_changes; took: 0:00:00.000221
DEBUG: Importing rule: git_remote_delete; took: 0:00:00.000247
DEBUG: Importing rule: git_remote_seturl_add; took: 0:00:00.000184
DEBUG: Importing rule: git_rm_local_modifications; took: 0:00:00.000264
DEBUG: Importing rule: git_rm_recursive; took: 0:00:00.000302
DEBUG: Importing rule: git_rm_staged; took: 0:00:00.000233
DEBUG: Importing rule: git_stash; took: 0:00:00.000233
DEBUG: Importing rule: git_stash_pop; took: 0:00:00.000260
DEBUG: Importing rule: git_tag_force; took: 0:00:00.000247
DEBUG: Importing rule: git_two_dashes; took: 0:00:00.000287
DEBUG: Importing rule: go_run; took: 0:00:00.000273
DEBUG: Importing rule: gradle_no_task; took: 0:00:00.001183
DEBUG: Importing rule: gradle_wrapper; took: 0:00:00.000379
DEBUG: Importing rule: grep_arguments_order; took: 0:00:00.000346
DEBUG: Importing rule: grep_recursive; took: 0:00:00.000372
DEBUG: Importing rule: grunt_task_not_found; took: 0:00:00.000639
DEBUG: Importing rule: gulp_not_task; took: 0:00:00.000453
DEBUG: Importing rule: has_exists_script; took: 0:00:00.000285
DEBUG: Importing rule: heroku_multiple_apps; took: 0:00:00.000331
DEBUG: Importing rule: heroku_not_command; took: 0:00:00.000280
DEBUG: Importing rule: history; took: 0:00:00.000137
DEBUG: Importing rule: hostscli; took: 0:00:00.000420
DEBUG: Importing rule: ifconfig_device_not_found; took: 0:00:00.000410
DEBUG: Importing rule: java; took: 0:00:00.000240
DEBUG: Importing rule: javac; took: 0:00:00.000303
DEBUG: Importing rule: lein_not_task; took: 0:00:00.000436
DEBUG: Importing rule: ln_no_hard_link; took: 0:00:00.000293
DEBUG: Importing rule: ln_s_order; took: 0:00:00.000463
DEBUG: Importing rule: long_form_help; took: 0:00:00.000143
DEBUG: Importing rule: ls_all; took: 0:00:00.000348
DEBUG: Importing rule: ls_lah; took: 0:00:00.000425
DEBUG: Importing rule: man; took: 0:00:00.000327
DEBUG: Importing rule: man_no_space; took: 0:00:00.000124
DEBUG: Importing rule: mercurial; took: 0:00:00.000345
DEBUG: Importing rule: missing_space_before_subcommand; took: 0:00:00.000105
DEBUG: Importing rule: mkdir_p; took: 0:00:00.000289
DEBUG: Importing rule: mvn_no_command; took: 0:00:00.000323
DEBUG: Importing rule: mvn_unknown_lifecycle_phase; took: 0:00:00.000367
DEBUG: Importing rule: no_command; took: 0:00:00.000398
DEBUG: Importing rule: no_such_file; took: 0:00:00.000180
DEBUG: Importing rule: npm_missing_script; took: 0:00:00.063259
DEBUG: Importing rule: npm_run_script; took: 0:00:00.000315
DEBUG: Importing rule: npm_wrong_command; took: 0:00:00.000378
DEBUG: Importing rule: open; took: 0:00:00.000335
DEBUG: Importing rule: pacman; took: 0:00:00.231445
DEBUG: Importing rule: pacman_not_found; took: 0:00:00.000160
DEBUG: Importing rule: path_from_history; took: 0:00:00.000129
DEBUG: Importing rule: php_s; took: 0:00:00.000312
DEBUG: Importing rule: pip_install; took: 0:00:00.000308
DEBUG: Importing rule: pip_unknown_command; took: 0:00:00.000300
DEBUG: Importing rule: port_already_in_use; took: 0:00:00.000678
DEBUG: Importing rule: prove_recursively; took: 0:00:00.000411
DEBUG: Importing rule: pyenv_no_such_command; took: 0:00:00.080183
DEBUG: Importing rule: python_command; took: 0:00:00.000285
DEBUG: Importing rule: python_execute; took: 0:00:00.000244
DEBUG: Importing rule: quotation_marks; took: 0:00:00.000087
DEBUG: Importing rule: react_native_command_unrecognized; took: 0:00:00.000309
DEBUG: Importing rule: remove_trailing_cedilla; took: 0:00:00.000127
DEBUG: Importing rule: rm_dir; took: 0:00:00.000255
DEBUG: Importing rule: rm_root; took: 0:00:00.000272
DEBUG: Importing rule: scm_correction; took: 0:00:00.000289
DEBUG: Importing rule: sed_unterminated_s; took: 0:00:00.000260
DEBUG: Importing rule: sl_ls; took: 0:00:00.000130
DEBUG: Importing rule: ssh_known_hosts; took: 0:00:00.000262
DEBUG: Importing rule: sudo; took: 0:00:00.000120
DEBUG: Importing rule: sudo_command_from_user_path; took: 0:00:00.000261
DEBUG: Importing rule: switch_lang; took: 0:00:00.000167
DEBUG: Importing rule: systemctl; took: 0:00:00.000388
DEBUG: Importing rule: test.py; took: 0:00:00.000100
DEBUG: Importing rule: tmux; took: 0:00:00.000286
DEBUG: Importing rule: touch; took: 0:00:00.000509
DEBUG: Importing rule: tsuru_login; took: 0:00:00.000273
DEBUG: Importing rule: tsuru_not_command; took: 0:00:00.000245
DEBUG: Importing rule: unknown_command; took: 0:00:00.000114
DEBUG: Importing rule: unsudo; took: 0:00:00.000108
DEBUG: Importing rule: vagrant_up; took: 0:00:00.000251
DEBUG: Importing rule: whois; took: 0:00:00.000368
DEBUG: Importing rule: workon_doesnt_exists; took: 0:00:00.000312
DEBUG: Importing rule: yarn_alias; took: 0:00:00.000248
DEBUG: Importing rule: yarn_command_not_found; took: 0:00:00.086066
DEBUG: Importing rule: yarn_command_replaced; took: 0:00:00.000458
DEBUG: Importing rule: yarn_help; took: 0:00:00.000263
DEBUG: Trying rule: dirty_unzip; took: 0:00:00.000111
No fucks given
DEBUG: Total took: 0:00:27.193200

If the bug only appears with a specific application, the output of that application and its version:

It seems to be slow regardless.

Anything else you think is relevant:

I’m not really sure what would cause it to evaluate slowly, each rule import and eval only takes a couple milliseconds, so it’s not the eval it feels like there’s a 20 second wait for it to spin up before it starts evaluating.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 20
  • Comments: 30 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Hey guys, I figured this out. it’s irrelevant to thefuck but your wsl machine.

Try echo $PATH and you probably gonna see a long list there, and that’s the reason the fuck is so slow. You can do what’s suggested here, https://github.com/Microsoft/WSL/issues/1640#issuecomment-616887435, and restart your linux distro.

After that thefuck runs smooth as fuck for me

Beware your vscode would be gone after that, so probably do which code first

I’ve created PR (#1165) which adds a setting to allow filtering paths - this could be used to prevent searching in /mnt paths under WSL which improves performance without needing to disable adding Windows paths to WSL (which has other negative side effects as noted in this thread)

@cforce I think set appendWindowsPath to false is not a good solution. Just for now or some one.

If remove env path from Windows side it will make VSCode can’t open in command on WSL. Maybe in another program will cause the same issue.

My opinion is thefuck should detect WSL and exclude Windows path by default or make some ENV variable to add prefix path to exclude from thefuck ?

As a crude starting point, what about defaulting excluded_search_path_prefixes to ["/mnt/c/WINDOWS"]?

I’m not saying that’s an excellent solution by any stretch, and hope it provokes better alternatives, but isn’t it better than the current state?

I tried this, as well as just using /mnt, but I’m still experiencing extremely slow performance.

image

Has anyone come up with any other solutions/workarounds/hacks?

EDIT: Almost immediately after posting this comment I noticed my path has a lot of references to /c rather than /mnt/c, changing the excluse to include ‘/c’ improved performance to what I am used to on native Mac/Linux.
I’m expecting this has something to do with our setup at my job, but wanted to leave a note of this here.

Hi, I found this issue after hitting the same thing. Is it right that #1165 closed this issue? Users (like myself) who install the next thefuck release on WSL will still hit a borderline-unusable delay with no indication of why. To fix it, the user has to care enough to start googling instead of just abandoning the tool, track down this github issue (surprisingly nontrivial unless you have prior knowledge that the issue is WSL-specific), find the comment or the MR with the exclusion setting, and apply it. It’s a huge improvement to have a setting available to resolve the issue on my box, and that’s fantastic, but it’s workaround, not a fix.

As a crude starting point, what about defaulting excluded_search_path_prefixes to ["/mnt/c/WINDOWS"]?

  • In my profiling, system32 accounted for a large majority of the time penalty, and the rest of C:\Windows accounted for a large majority of the remainder
  • Most people have Windows mounted on C:
  • Yes this “stops” people from using thefuck for C:\Windows executables while on WSL. But they already couldn’t do that - the perf was basically unusable

I’m not saying that’s an excellent solution by any stretch, and hope it provokes better alternatives, but isn’t it better than the current state?

I created a new Wiki page called Troubleshooting and added this fix to it. I’m not familiar with any style guidelines for Github Wiki pages (if there even is such a thing), so feel free to edit it if something doesn’t look right!

Oh, I thought you meant the installation process.

That would be a nice thing to have. Any ideas how that can be done? PR’s are more than welcome.

Did that, see #1236. Also, I couldn’t help with the more examples… #1235

Same problem on WSL 2 ubuntu 18.04 Install with pip3

$ thefuck --version
The Fuck 3.30 using Python 3.8.2 and ZSH 5.8

I also have the same issue with WSL on Windows 10 and The Fuck 3.29 using Python 3.6.9 and Bash 4.4.20(1)-release From purely anecdotal experience, it seems like git commands take the longest for fuck to return options.