![]() |
Check if a command is valid
Hello,
I have to figure out if a string is callable on a Linux system. I'm actually doing this: def is_valid_command(command): retcode = 100 # initialize if command: retcode = subprocess.call(command, shell=True) if retcode is 0: print "Valid command." else: print "Looks not so good..." is_valid_command("ls") Never mind the code, because this is not the original. The side effect of subprocess.call() is that it *actually* executes it, but I just need the return code. What are better ways of doing this? |
Re: Check if a command is valid
On Mon, Jul 12, 2010 at 6:29 PM, Kenny Meyer <knny.myer@gmail.com> wrote:
> Hello, > > I have to figure out if a string is callable on a Linux system. I'm "callable" seems vague. Is a command string with invalid arguments but a valid executable "callable"? If no, then there's no general way to test "callability" without actually running the command. > actually doing this: > > Â* Â*def is_valid_command(command): > Â* Â* Â* Â*retcode = 100 # initialize > Â* Â* Â* Â*if command: > Â* Â* Â* Â* Â* Â*retcode = subprocess.call(command, shell=True) > Â* Â* Â* Â*if retcode is 0: That should be `== 0`, not `is 0`. The fact that `is 0` just so happens to work is an implementation detail. > Â* Â* Â* Â* Â* Â*print "Valid command." > Â* Â* Â* Â*else: > Â* Â* Â* Â* Â* Â*print "Looks not so good..." > > Â* Â*is_valid_command("ls") > > Never mind the code, because this is not the original. > The side effect of subprocess.call() is that it *actually* executes > it, but I just need the return code. Well, you're not gonna be able to get the command's return code without actually running it (unless perhaps you're referring to a return code from the shell itself?). > What are better ways of doing this? One idea: from shlex import split as shell_tokenize from subprocess import check_output def is_valid_command(command): try: executable = shell_tokenize(command)[0] except (ValueError, IndexError):# invalid shell syntax return False return bool(check_output(['which', executable]))# on the PATH? Cheers, Chris -- http://blog.rebertia.com |
Re: Check if a command is valid
Kenny Meyer wrote:
> Hello, > > I have to figure out if a string is callable on a Linux system. I'm > actually doing this: > > def is_valid_command(command): > retcode = 100 # initialize > if command: > retcode = subprocess.call(command, shell=True) > if retcode is 0: > print "Valid command." > else: > print "Looks not so good..." > > is_valid_command("ls") > > Never mind the code, because this is not the original. > The side effect of subprocess.call() is that it *actually* executes > it, but I just need the return code. What are better ways of doing > this? > I'm not sure I get exactly what you're searching for but here's something that may help. If you just whant to know if a command (without parameter) is a Linux command (either a builtin, alias of file exe) you can use the "where" command and inspect its return code, the command is not executed though. >where ls ls is an alias for ls --color=auto -F ls is /bin/ls >where apt-get apt-get is /usr/bin/apt-get >where doesnotexists doesnotexists not found zsh: exit 1 retcode = subprocess.call(command, shell=True) becomes retcode = subprocess.call("where " + command) JM NB : this does not work with parameters appened to the command. |
Re: Check if a command is valid
On Tue, Jul 13, 2010 at 4:33 AM, Jean-Michel Pichavant
<jeanmichel@sequans.com> wrote: > Kenny Meyer wrote: >> I have to figure out if a string is callable on a Linux system. I'm >> actually doing this: >> >> Â* Â*def is_valid_command(command): >> Â* Â* Â* Â*retcode = 100 # initialize >> Â* Â* Â* Â*if command: >> Â* Â* Â* Â* Â* Â*retcode = subprocess.call(command, shell=True) >> Â* Â* Â* Â*if retcode is 0: >> Â* Â* Â* Â* Â* Â*print "Valid command." >> Â* Â* Â* Â*else: >> Â* Â* Â* Â* Â* Â*print "Looks not so good..." >> >> Â* Â*is_valid_command("ls") >> >> Never mind the code, because this is not the original. >> The side effect of subprocess.call() is that it *actually* executes >> it, but I just need the return code. What are better ways of doing >> this? >> > > I'm not sure I get exactly what you're searching for but here's something > that may help. > > If you just whant to know if a command (without parameter) is a Linux > command (either a builtin, alias of file exe) you can use the "where" > command and inspect its return code, the command is not executed though. > >>where ls > ls is an alias for ls --color=auto -F > ls is /bin/ls >>where apt-get > apt-get is /usr/bin/apt-get >>where doesnotexists > doesnotexists not found > zsh: exit 1 `where` seems to be a zsh built-in: $ # I'm in UR bash $ nonexistent -bash: nonexistent: command not found $ where bash -bash: where: command not found And not everyone has zsh installed, so... I don't see why one shouldn't use the standard `which` *nix command instead.. Also, in retrospect, my suggestion should probably have checked the return code rather than the output; more efficient and simple that way. Cheers, Chris -- http://blog.rebertia.com |
Re: Check if a command is valid
Chris Rebert wrote:
> `where` seems to be a zsh built-in: > $ # I'm in UR bash > $ nonexistent > -bash: nonexistent: command not found > $ where bash > -bash: where: command not found > > And not everyone has zsh installed, so... > I don't see why one shouldn't use the standard `which` *nix command instead. Because `which` ia a C shell script. It reads your .cshrc, to see which aliases would be defined if you were to use the C shell, but it doesn't look at your .bashrc. You're probably better off using `type`: it knows about built-ins and shell functions and that sort of stuff: $ which type /usr/bin/type $ type type type is a shell builtin $ Guess which answer is more relevant to you ..... HTH, -- HansM |
Re: Check if a command is valid
Chris Rebert (clp2@rebertia.com) wrote:
> On Mon, Jul 12, 2010 at 6:29 PM, Kenny Meyer <knny.myer@gmail.com> wrote: > > Hello, > > > > I have to figure out if a string is callable on a Linux system. I'm > > "callable" seems vague. Is a command string with invalid arguments but > a valid executable "callable"? If no, then there's no general way to > test "callability" without actually running the command. I'm glad you pointed that out, because you're right. I subconciously meant a file that is in the $PATH. [snip] > > Well, you're not gonna be able to get the command's return code > without actually running it (unless perhaps you're referring to a > return code from the shell itself?). > > > What are better ways of doing this? > > One idea: > > from shlex import split as shell_tokenize > from subprocess import check_output > > def is_valid_command(command): > try: > executable = shell_tokenize(command)[0] > except (ValueError, IndexError):# invalid shell syntax > return False > return bool(check_output(['which', executable]))# on the PATH? > I have tried this and found some unexpected issues with Python 2.6 which I though I should point out: Firstly, the function `check_output` in the `subprocess` module only comes with Python 2.7, but I have found a similar function called `check_call` [1] which seems is similar, but not the same. [1] http://docs.python.org/library/subpr...ess.check_call The code now looks like this: from shlex import split as shell_tokenize from subprocess import check_call, CalledProcessError def is_valid_command(command): try: executable = shell_tokenize(command)[0] check_call(['which', executable]) # Raises CalledProcessError if # something went wrong return True except (ValueError, IndexError, CalledProcessError): # Catch exception if there # was an error calling the process return False The idea with `which` is really great one. Thanks a lot, for your time and your input. -- Onward and upwards, Kenny Meyer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAkw84gwACgkQ+/8gJfVrobKgrgCeMQ8WNJRAiiZABP5N+PSz/gHX PmYAniP9otwBOF68h+npy0DXv51z8pTN =8nta -----END PGP SIGNATURE----- |
Re: Check if a command is valid
On Jul 13, 4:14*pm, Hans Mulder <han...@xs4all.nl> wrote:
> Chris Rebert wrote: > > `where` seems to be a zsh built-in: > > $ # I'm in UR bash > > $ nonexistent > > -bash: nonexistent: command not found > > $ where bash > > -bash: where: command not found > > > And not everyone has zsh installed, so... > > I don't see why one shouldn't use the standard `which` *nix command instead. > > Because `which` ia a C shell script. *It reads your .cshrc, to see which > aliases would be defined if you were to use the C shell, but it doesn't > look at your .bashrc. > > You're probably better off using `type`: it knows about built-ins and > shell functions and that sort of stuff: > > $ which type > /usr/bin/type > $ type type > type is a shell builtin > $ > > Guess which answer is more relevant to you ..... > > HTH, > > -- HansM Oh thanks, Hans! `type` seems to a good alternative. Surely it can also get the job (better) done. |
Re: Check if a command is valid
On 07/12/10 21:29, quoth Kenny Meyer:
> Hello, > > I have to figure out if a string is callable on a Linux system. I'm > actually doing this: > > def is_valid_command(command): > retcode = 100 # initialize > if command: > retcode = subprocess.call(command, shell=True) > if retcode is 0: > print "Valid command." > else: > print "Looks not so good..." > > is_valid_command("ls") > > Never mind the code, because this is not the original. > The side effect of subprocess.call() is that it *actually* executes > it, but I just need the return code. What are better ways of doing > this? Luke! Use the force! #! /usr/bin/python import os def is_valid_command(command): looking_good = False for ii in os.environ['PATH'].split(':'): if os.access(ii + '/' + command, os.X_OK): looking_good = True break print ["Looks not so good...", "Valid command."][looking_good] is_valid_command('python') is_valid_command('pythoon') This way you don't start up any subprocesses and you are actually doing what the shell would do for you. THE ONLY DIFFERENCE is that a persistent bash would hash all of the contents of what lives in PATH and so might have a slight shot of being faster under somewhat obscure conditions. I would strongly encourage you to not execute an arbitrary string to see if it returns a pretty return code. is_valid_command('{cd /; rm -rf /}') Warning: * It only checks if the command exists in PATH and is executable TO YOU: * Do not make fun of is_valid_command. It will get angry. * You might also want to beef it up a la pp = ii + '/' + command if os.access(pp, (os.X_OK) and not os.stat.isdir(p)): so you are checking executable files and not directories etc... * More warnings can be amplified upon over pitchers of beer. -- Time flies like the wind. Fruit flies like a banana. Stranger things have .0. happened but none stranger than this. Does your driver's license say Organ ..0 Donor?Black holes are where God divided by zero. Listen to me! We are all- 000 individuals! What if this weren't a hypothetical question? steveo at syslang.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iEYEARECAAYFAkw+IRwACgkQRIVy4fC+NyT+EgCgg3fJy58fMn K9Y/HvBe6HzLtU sRQAnAr1vr7cLsei1eDS6Yr6deolMLeL =SnuZ -----END PGP SIGNATURE----- |
Re: Check if a command is valid
On 2010-07-14, Steven W. Orr <steveo@syslang.net> wrote:
> On 07/12/10 21:29, quoth Kenny Meyer: > >> I have to figure out if a string is callable on a Linux system. I'm >> actually doing this: >> >> def is_valid_command(command): >> retcode = 100 # initialize >> if command: >> retcode = subprocess.call(command, shell=True) >> if retcode is 0: >> print "Valid command." >> else: >> print "Looks not so good..." >> >> is_valid_command("ls") >> >> Never mind the code, because this is not the original. The side >> effect of subprocess.call() is that it *actually* executes it, but I >> just need the return code. What are better ways of doing this? > > Luke! Use the force! > > #! /usr/bin/python > > import os > def is_valid_command(command): > looking_good = False > for ii in os.environ['PATH'].split(':'): > if os.access(ii + '/' + command, os.X_OK): > looking_good = True > break > print ["Looks not so good...", "Valid command."][looking_good] > > is_valid_command('python') > is_valid_command('pythoon') Just to be clear, that's not the same as the OP's code in two respects: 1) It doesn't handle shell builtins or aliases. 2) It determines not whether a command is valid (returns 0), but whether a command exists as an executable. "Valid" is a rather small subset of "exists". Of course the OP didn't explain what he meant by "callable", so all we have to go on is his posted code. > This way you don't start up any subprocesses and you are actually > doing what the shell would do for you. > > THE ONLY DIFFERENCE is that a persistent bash would hash all of the > contents of what lives in PATH and so might have a slight shot of > being faster under somewhat obscure conditions. No, there are other differences. See above. > I would strongly encourage you to not execute an arbitrary string to > see if it returns a pretty return code. > > is_valid_command('{cd /; rm -rf /}') > > Warning: > * It only checks if the command exists in PATH and is executable TO > YOU: Which is different than determining whether a command (including arguments) is valid (callable and returns 0). However, running a command to determine if it's valid is going to cause problems sooner or later due to side-effects of that command. For example, the first time you the command "rm /path/to/a/file" it may be valid, but the second time it won't be. > * Do not make fun of is_valid_command. It will get angry. And don't taunt happy fun ball! > * You might also want to beef it up a la > pp = ii + '/' + command > if os.access(pp, (os.X_OK) and not os.stat.isdir(p)): > so you are checking executable files and not directories etc... > * More warnings can be amplified upon over pitchers of beer. -- Grant Edwards grant.b.edwards Yow! My mind is making at ashtrays in Dayton ... gmail.com |
| All times are GMT. The time now is 06:19 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.