-
-
Notifications
You must be signed in to change notification settings - Fork 632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: how make sudo expand aliases? #2618
Comments
Hi @t184256 - thanks for bringing this up! I think this might be an oversight more that a question. Your workaround certainly is effective. For Tab completion, the code to expand the aliases is at xonsh/xonsh/completers/commands.py Line 32 in 5a2c077
In terms of expanding the command and running it, I think you are doing it correctly. Something like this should probably just be part of xonsh itself. If you felt like putting in a PR to modify aliases.py that would be awesome! |
### Motivation * We have no recommended way to force subprocess command be (un)threadable * #4214 * #2119 * #5003 * It's interesting opportunity to have a way to modify specs and CP using `SpecModifierAlias`. ### Before ```xsh !(ssh host -T "echo 1") # output='' # EXPECTED: 1 __xonsh__.commands_cache.threadable_predictors['ssh'] = lambda *a, **kw: True !(ssh host -T "echo 1") ``` ### After ```xsh xthread # Mark command as threadable. !(xthread ssh host -T "echo 1") # output='1' ``` Closes: * Closes #4214 * Closes #2119 * Partially closes #5003 Implementation of `SpecModifierAlias` will help in: * #2618 JFYI #5413 ## For community ⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍 comment** --------- Co-authored-by: a <1@1.1> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Gil Forsyth <gforsyth@users.noreply.github.com>
Show std if `$XONSH_TRACE_SUBPROC=3`. ### Motivation * It's very helpful if you want to understand how subproc is working. * It's helpful to trace `SpecModifierAlias`. * It's helpful to trace cases like #2618 ## For community ⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍 comment** --------- Co-authored-by: a <1@1.1> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
I spent past month on diving into xonsh processes. I'm not jedi yet but this issue seems to be interesting and to be clear I want to describe the situation step by step and give a solution. I like xonsh and I'm glad to help. IntroIn fact at this time there is no elegant machinery in xonsh that allows modify subprocess command arguments. All we have is wrapping it into callable alias or exec alias if we need something more than just adding arguments. On the first look we can do something like this: aliases['xsudo'] = 'sudo -- @(aliases.eval_alias($args))' It works and looks pretty elegant and some day it will work as expected but today we have threading, capturing, resolving and prediction. These four terms are special terms in context of xonsh. This example above is exec alias that is short way to write callable alias in fact. And all four friends play game as well here too. The caseThere is a gap between an alias that is just a string that is equal to list of arguments and wrappers like callable alias or exec alias. When you run string alias it will be represented as a command and executed directly. But when you wrap it into the callable alias it creates the group of layers between the command execution and outer world and you need jedi's midichlorians with knowledge of xonsh internals to manage the force. This all is not needed for simple tasks where you need to just run command per command in callable alias. But in the case with sudo you facing with knot between threading, capturing, resolving and prediction. I'm only going to describe it in general terms because the truth is only in the code. Dive into rabbit holeFirst of all we need to understand what process we want to wrap into the alias: capturable (non interactive) or uncapturable (interactive). The Second thing you know that you want to use Third thing you should know is that Finally we see that both sudo and the process can be capturable or uncapturable. For complete clarity when you run the capture only stdout operator But when you want to put this into the callable alias you will have additional stdin, stdout, stderr and you need to implement support of threaded and unthreaded commands in the callable alias. And this is why scopatz show the example with read-writing the output here and this is why wrapping into the callable alias is the jedi path. Stop, back and making new pathInstead of doing wrapping into callable alias in the 0.17.0 I introduced I'm not crazy about this, but it does solve some issues until we get rid of threads or make it very clear how callable aliases work. Current solutionStarting from 0.17.0 you can directly change the command arguments and be confident that command will behave like you write all of this manually. Here it is: from xonsh.procs.specs import SpecModifierAlias
class SpecModifierExpandAlias(SpecModifierAlias):
def on_modifer_added(self, spec):
spec.cmd = spec.cmd[:1] + ['--'] + __xonsh__.aliases.eval_alias(spec.cmd[1:])
spec.args = spec.cmd
aliases['expand'] = SpecModifierExpandAlias()
aliases['xsudo'] = "expand sudo" Now it's working as expected (as expected in xonsh): which ls
# ls -G
$XONSH_TRACE_SUBPROC=2
xsudo ls
# ['sudo', '--', 'ls', '-G']
xsudo ls -a
# ['sudo', '--', 'ls', '-G', '-a']
xsudo ls | less
# ['sudo', '--', 'ls', '-G'] | less
# working
$(xsudo ls -a | grep file)
# ['sudo', '--', 'ls', '-G', '-a'] | grep file
# working Note! This is PoC and probably you need support of At the endDiving into this issue I realized we need command generator alias. So we have string/args alias and callable alias and we need something in the middle - alias that returns command e.g.
This command generator can solve also the case with piping i.e. |
Originally posted by @bennyyip in #5473 (comment) To prefix from xonsh.built_ins import XSH
from prompt_toolkit.filters.app import vi_insert_mode
@events.on_ptk_create
def custom_keybindings(bindings, **kw):
handle = bindings.add
def handle_prefix(prefix):
def handler(event):
text = event.current_buffer.text
if text.strip() == '':
# use last cmd if line is empty
event.current_buffer.auto_up()
text = event.current_buffer.text
if not text.strip().startswith(prefix):
expanded_text = XSH.aliases.expand_alias(text, len(text) + 1)
event.current_buffer.transform_current_line(lambda x: f'{prefix} {expanded_text}')
event.current_buffer.cursor_position += len(expanded_text) - len(text) + len(prefix) + 1
return handler
handle('escape', 'escape', filter=vi_insert_mode)(handle_prefix('sudo'))
handle('c-x', 'c-p', filter=vi_insert_mode)(handle_prefix('proxychains -q')) Double click |
Thank you for sharing this @bennyyip! It will be cool to have a xontrib based on xontrib-template for sharing this to people. |
What is the official way to make sudo expand aliases, like
alias sudo='sudo '
on bash?This is what I tried:
This works, but it's kinda verbose and pollutes the environment.
That one is a syntax error around the
return sudo_expanding_aliases
and I have no idea why. It's also even more verbose and ugly.Am I thinking in the correct direction? Is it a good idea in general? Am I doing the expansion right? How can I reduce environmental pollution?
For community
⬇️ Please click the 👍 reaction instead of leaving a
+1
or 👍 commentThe text was updated successfully, but these errors were encountered: