meganz / MEGAcmd

Command Line Interactive and Scriptable Application to access MEGA
Other
1.95k stars 406 forks source link

Mega auto-completion script taking very long to finish on Ubuntu 20.04 WSL #696

Open everlasterVR opened 2 years ago

everlasterVR commented 2 years ago

I installed mega-cmd from apt for Ubuntu 20.04 WSL. Wait time for opening a shell went from a few seconds to closer to a minute 😐

Opening a new shell sources .bashrc which sources the file /usr/share/bash-completion/bash_completion, and during that the file megacmd_completion.sh is sourced from /etc/bash_completion.d.

To see what's taking so long during that I ran

set -x
. /usr/share/bash-completion/bash_completion

Here's the output:

<truncated>
++ for i in "$compat_dir"/*
++ [[ megacmd_completion.sh != @(@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))|Makefile*|@(acroread.sh)) ]]
++ [[ -f /etc/bash_completion.d/megacmd_completion.sh ]]
++ [[ -r /etc/bash_completion.d/megacmd_completion.sh ]]
++ . /etc/bash_completion.d/megacmd_completion.sh
++++ compgen -ca
++++ grep mega-

This is where it gets very slow. After closer to a minute, I get an output of a long list of for loops, this is just the very beginning:

+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-reload
+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-export
+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-passwd
+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-mount
+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-share
+++ for i in $(compgen -ca | grep mega-)
+++ IFS=' '
+++ complete -o default -F _megacmd mega-import
+++ for i in $(compgen -ca | grep mega-)
<truncated>

It seems like some optimizing needs to be done here to allow /etc/bash_completion.d/megacmd_completion.sh to be sourced in a reasonable amount of time.

As a temporary fix, I moved the file away from bash_completion.d: sudo mv /etc/bash_completion.d/megacmd_completion.sh ~. For my use case, that's fine since I only intend to use megacmd programmatically.

polmr commented 2 years ago

That's odd, such completion script should run in a timely manner.

I wonder what's taking the time: the complete commands (which sets completion for all available commands), or the compgen -ca. (probably the later, which in the would probably need to look for executables in all PATH). I believe we could speed that up by getting the list of mega-X commands from elsewhere.

perttiarjanne commented 2 years ago

Quick Fix I did experience exactly similar slowness in /etc/bash_completion.d/megacmd_completion.sh. The loop itself is not the problem but the ridiculously slow linux command compgen -ca that is to be blamed. There is another minor buggy feature: the list produced by compgen -ca | grep mega- contains duplicates, yet they could be easily removed with | sort | uniq (if those are available). Never the less, I found it best to simply replace compgen -ca with ls /usr/bin. In my installation /usr/bin contains all mega- commands. Now megacmd_completion.sh runs fast like charm.

Cnoor0171 commented 1 year ago

Instead of getting the list of all commands with compgen -ca (which can generate thousands of commands) and then filtering with grep mega-, it is much faster to let compgen do the filtering. I replaced compgen -ca | grep mega- with compgen -ca mega- and now it takes less than a second as opposed to 40 seconds.

The two are not exactly equivalent, but I think the second one is the correct one. For example compgen -ca | grep mega- will also list things like omega-something if you have that in your path, while compgen -ca mega- won't.

PaoloOranges commented 1 year ago

I had the same problem and tested @Cnoor0171 fix. It wokrs like a charm. @polmr can we open a PR?

ziltsh commented 1 year ago

As it is now, painfully slow (though not as bad as 40 seconds, but still noticable): ~# time compgen -ca | grep mega- >>/dev/null real 0m0.294s user 0m0.048s sys 0m0.265s

As it could be: ~# time compgen -ca mega- >>/dev/null real 0m0.010s user 0m0.001s sys 0m0.009s

Please consider.

~# lsb_release -d Description: Debian GNU/Linux 11 (bullseye)

svoboda18 commented 1 year ago

it is extremely slow in Ubuntu 18.04, it is taking a couple of minutes, which is absurd.