Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

How does this handle pipes and such? What's the nicest python equivalent to `grep ^$(whoami) /etc/passwd | awk -F : '{print $NF}'`?


Here are three options:

    # Option 1 (no pipes)
    import os
    for line in open("/etc/passwd").read().splitlines():
        fields = line.split(":")
        if fields[0] == os.getlogin():
            print(fields[-1])

    # Option 2 (Cheating, but not really. For most problems worth solving, there exists a library to do the work with little code.)
    import os
    print(os.environ['SHELL'])

    # Option 3 (pipes, not sure if the utf-8 thing can be done nicer somehow)
    import subprocess
    username = subprocess.check_output("whoami", encoding="utf-8").rstrip()
    p1 = subprocess.Popen(["grep", "^" + username, "/etc/passwd"], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(["awk", "-F", ":", "{print $NF}"], stdin=p1.stdout, stdout=subprocess.PIPE)
    print(p2.communicate()[0].decode("utf-8"))


Thanks, that does answer my question quite thoroughly:) I intended the question not as "how would I get my shell" but as a "how would I pipe commands together", which now that I think about it is perhaps the real issue: I think about solving many problems from the perspective of "how would I do this in /bin/sh?", but perhaps the real answer is that if you're doing it in Python (or whatever) then you should be writing a solution that's idiomatic in that language. Or if you like, perhaps one doesn't need to "standard library" of coreutils if one has the Python standard library, which means that many of the thing's I'd miss in Python are hard because they aren't the right solution there.


Quickest and dirtiest way I've found, but yes, not idiomatic Python:

    subprocess.check_output("grep ^$(whoami) /etc/passwd | awk -F : '{print $NF}'", shell=True, encoding="utf-8").strip()
I didn't test that particular line, but in general this is how I execute shell pipelines in Python.


:) I agree that that works, of course, but if we have to use shell=True and just shove the whole thing like that then it loses a rather lot of the "Python" appeal. Still valuable if you need to feed the output into Python, of course.


The answer to" how I pipe shell commands in Python" is that you can do it (e.g., using plumbum, fabric, pexpect, subprocess), but you shouldn't in most cases.

In bash, you have to use commands for most things. In Python, you don't.

For example, `curl ... | jq ...` shell pipeline would be converted into requests/json API in Python.


Nothing is quite as succinct as shell. The python equivalent to this would probably be at least 10 lines of code.


Everyone tends to rag on Perl, but it's excellent in this space.

Edit: The equivalent of above would be:

  #!/usr/bin/perl
  my $shell=(getpwuid($>))[8];
  print "$shell\n";
Though it does have simple syntax for pipes as well.


https://news.ycombinator.com/item?id=24558719 does it in 5, which is, I think, proof that you're both right. (Of course, perhaps shell is cheating, since I chained 3 commands into that one-liner, and 2 of those are really their own languages with further subcommands.)


    pwd.getpwnam(getpass.getuser()).pw_shell




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: