tomerfiliba / plumbum

Plumbum: Shell Combinators
https://plumbum.readthedocs.io
MIT License
2.8k stars 182 forks source link

wildcard characters in commands like ls and rm #512

Open kfaseela opened 4 years ago

kfaseela commented 4 years ago

Hi, I have a small script as below, which is not able to recognize "*" in the path. What is the right way to do this? from plumbum import local ls = local["ls"] chain = ls["/home/faseela/*"] print(chain) chain()

output >>>

plumbum.commands.processes.ProcessExecutionError: Unexpected exit code: 2 Command line: | /bin/ls '/home/faseela/' Stderr: | /bin/ls: cannot access '/home/faseela/\': No such file or directory

Similarly, i tried "rm" command. It does not work as expected as well.

AndydeCleyre commented 4 years ago

The asterisk isn't really part of the path or command. You can use the division operator for globbing. Check this page of the guide for "globing" [sic].

kfaseela commented 4 years ago

Could you please tell me how I should be doing the above ls command to get globbing work?

chain = ls["/home/faseela/*"]

kfaseela commented 4 years ago

p = local.path("/home/faseela") ls = local["ls"] ls[p // "*"]()

it works this way. But would have been far easier if I can do this without the need for constructing path for the parent and then doing globing. Let me know if there is an option for the same

AndydeCleyre commented 4 years ago

There are some other ways to do this, depending on what your actual goal is. If you want to get a list of filenames, any of these will do:

from plumbum import local
# 1:
local.path('/home/faseela').list()
# 2:
local.path('/home/faseela') // '*'

from plumbum.cmd import ls
# 3:
ls('/home/faseela')

And some more, but again, it depends on what you really need to accomplish. IMO using ls at all should be avoided, as this isn't an interactive shell, and ls implementations can theoretically vary from system to system. We can get more predictable results by using plumbum's path handling.

If you're implementing a full interactive shell, again, I recommend looking at prompt toolkit, or whatever xonsh/daudin/mario are doing.

kfaseela commented 4 years ago

Unfortunately I have not yet looked into prompt toolkit, and still using Plumbum at the backend of an interactive shell. My use case is to allow something similar to "ls *" from the console. Using something like below generically, which does not work for "*"


def plumbum_command_builder(command_name, command_params=None):
    try:
        command = local[command_name]
    except CommandNotFound:
        return command_name
    return command[command_params]
AndydeCleyre commented 4 years ago

You may want to either: