Live data from Hacker News

Ctypes.sh – A foreign function interface for bash

ctypes.sh

31–39 of 39 posts

Re: Ctypes.sh – A foreign function interface for bash

#31

Earlier quoted context omitted.

I don't think it's a big pain in python. I imagine ruby wouldn't be terrible either: #!/usr/bin/env python import sys, os, subprocess, glob os.chdir(os.path.dirname(sys.argv[0])) for test in glob.glob("*.in"): test = os.path.splitext(test)[0] infile = test + ".in" outfile = test + ".out" output = subprocess.check_output(["./whofrom", infile], stderr=subprocess.STDOUT) expected = open(outfile, 'r').read() if output !=…

One issue is the problem of indirect documentation, and it comes down to this one line: "import sys, os, subprocess, glob". How do you find which module you need? Search on the web may be the best answer. In shell at least you have "man -k". Once I know the module, how do I get its documentation? Here at least there is an answer: import glob; help(glob); But how good is this documentation? If I do it I get: glob(path…

> How do you find which module you need? Search on the web may be the best answer.

Experience, stdlib reference, web searches. Same as with bash.

> In shell at least you have "man -k".

I really disagree here. Since you took `glob` as an example, how do you get to the explanation of `for test in *.in`? Go on, try that with "man -k".

> Already python is telling me that the "man" documentation is going to be better

I'm not trying to say python is good here (well, the stdlib documentation on the web is actually pretty good, it's just not easily available from the console). But the idea that bash/man is more discoverable is just wrong... You can find the glob under "Pattern Matching" section which is all right, but you need to understand most of the expansion mechanism of shell to know it applies to "for". Then again "for" itself has a definition that belongs more to a CS material, than to a usage guide.

Re: Ctypes.sh – A foreign function interface for bash

#32

Earlier quoted context omitted.

One issue is the problem of indirect documentation, and it comes down to this one line: "import sys, os, subprocess, glob". How do you find which module you need? Search on the web may be the best answer. In shell at least you have "man -k". Once I know the module, how do I get its documentation? Here at least there is an answer: import glob; help(glob); But how good is this documentation? If I do it I get: glob(path…

> How do you find which module you need? Search on the web may be the best answer. Experience, stdlib reference, web searches. Same as with bash. > In shell at least you have "man -k". I really disagree here. Since you took `glob` as an example, how do you get to the explanation of `for test in *.in`? Go on, try that with "man -k". > Already python is telling me that the "man" documentation is going to be better I'm…

Well I agree that glob was not the best example. For sure there are things you have to learn about shell scripting as well.. one of them is if "man for" doesn't work, try "help for" or "man bash". In fact there is no good reason for this and it should be improved. (not to mention that you already had to know what *.in does, but you could argue that this is fundamental shell syntax: man bash / pattern matching).

Re: Ctypes.sh – A foreign function interface for bash

#33

Earlier quoted context omitted.

The best use-case I can think of is using bash as a REPL for C libraries. Many times in the past, I've made library calls that either misinterpreted the parameters or the result value. I would have loved the ability to prototype those calls in bash until I understood them enough to call them properly.

You can use gdb as an REPL for C.

Reminds me of vxworks: the main shell for the operating system is the debugger.

Re: Ctypes.sh – A foreign function interface for bash

#34

Earlier quoted context omitted.

One issue is the problem of indirect documentation, and it comes down to this one line: "import sys, os, subprocess, glob". How do you find which module you need? Search on the web may be the best answer. In shell at least you have "man -k". Once I know the module, how do I get its documentation? Here at least there is an answer: import glob; help(glob); But how good is this documentation? If I do it I get: glob(path…

> How do you find which module you need? Search on the web may be the best answer. Experience, stdlib reference, web searches. Same as with bash. > In shell at least you have "man -k". I really disagree here. Since you took `glob` as an example, how do you get to the explanation of `for test in *.in`? Go on, try that with "man -k". > Already python is telling me that the "man" documentation is going to be better I'm…

Since you took `glob` as an example, how do you get to the explanation of `for test in .in`?*

`man -k wildcard` points to `man 3am fnmatch` which points to `man 3 fnmatch`. Now the process for python and shell converge, and I still have to know to look at the "See Also" section of the manpage to find `man 7 glob` which finally gives me useful information.

The python workflow involved one fewer discrete step, but the user would have to know both help() in the python REPL and how to navigate man pages, while for shell scripts the user only needed to know how to navigate man pages.

I'm not trying to say python is good here (well, the stdlib documentation on the web is actually pretty good, it's just not easily available from the console). But the idea that bash/man is more discoverable is just wrong... You can find the glob under "Pattern Matching" section which is all right, but you need to understand most of the expansion mechanism of shell to know it applies to "for". Then again "for" itself has a definition that belongs more to a CS material, than to a usage guide.

I do very much agree with you here. Man pages are not very accessible. Some man pages (most that I work with, but I understand that's not everyone's experience) are very good, complete, and understandable. I'd be comfortable saying that python's and the shell's documentation features are roughly equally usefule ± some small amount.

Re: Ctypes.sh – A foreign function interface for bash

#35
post #26

Earlier quoted context omitted.

No such example; after all, you can spawn a shell subprocess in any of those. There's just certain types of tasks where you can more clearly express your intent in a shell script. If, for example, you need to spawn a ton of subprocesses, you can do that in any scripting language, but shell is designed from the ground up to launch subprocesses — it's most basic purpose is to launch programs. And so while I can't give…

I don't think it's a big pain in python. I imagine ruby wouldn't be terrible either: #!/usr/bin/env python import sys, os, subprocess, glob os.chdir(os.path.dirname(sys.argv[0])) for test in glob.glob("*.in"): test = os.path.splitext(test)[0] infile = test + ".in" outfile = test + ".out" output = subprocess.check_output(["./whofrom", infile], stderr=subprocess.STDOUT) expected = open(outfile, 'r').read() if output !=…

I'd argue that that's significantly worse at conveying the intent than the shell script version.

The shell script started as a workflow that was executed repeatedly, manually, from the shell, and then automated. Naturally, the shell script resembles very closely they commands typed in at the shell, with some added code to encode the part of the routine that was executed in the user's head.

The python script doesn't look anything like the routine that was previously entered at the shell. That makes it harder to tell at a glance that this script does the same thing.

It it horrible? No absolutely not. If you're working on a team where everyone knows python but not everyone is comfortable with shell scripts, then writing the script in python is the clear best option. But if you're working on a team where everyone is comfortable with both python and shell scripts, the shell script probably wins out.

Re: Ctypes.sh – A foreign function interface for bash

#36
post #12

Earlier quoted context omitted.

I disagree. Shell scripts are great for automating system tasks — for sysadminy type stuff, including tasks with high complexity with nested loops and conditionals. A scripting language like those you mentioned is great for if you need to run your script on systems you don't control, or you need it to be cross platform, or you'd describe what you're doing as creating software rather than automating tasks. No scriptin…

Can you give a shell script example of something that perl/python/ruby/nodejs can't do?

Set environment variables in the calling shell. Because you cannot run Python etc via "source".

Re: Ctypes.sh – A foreign function interface for bash

#38
post #28
post #23

Earlier quoted context omitted.

> Can you give a shell script example of something that perl/python/ruby/nodejs can't do? Install perl/python/ruby and nodejs -- requiring just the shell to be installed? Snark aside (it's not only snark - pretty much every system will have something like a posix shell), proper posix portable shell is hard - it's an old gnarly language -- but it's what we've got. And with a bit of discipline and good practices -- it…

> Install perl/python/ruby and nodejs -- requiring just the shell to be installed? You can run several of those languages (python for sure, but also perl IIRC) as a shell.

As a system shell? In theory, perhaps. But migrating a typical Linux/bsd distribution away from having any dependency in the shell would be a major undertaking. While some distributions already ship with only shell/busybox.

Re: Ctypes.sh – A foreign function interface for bash

#39
post #23

Earlier quoted context omitted.

> Can you give a shell script example of something that perl/python/ruby/nodejs can't do? Install perl/python/ruby and nodejs -- requiring just the shell to be installed? Snark aside (it's not only snark - pretty much every system will have something like a posix shell), proper posix portable shell is hard - it's an old gnarly language -- but it's what we've got. And with a bit of discipline and good practices -- it…

> Install perl/python/ruby and nodejs -- requiring just the shell to be installed? I just meant using any one of them, not all of them. And you can pretty much always rely on python and perl being installed. But my point is that if you're doing something other than a one-off thing, then it belongs to some project and you're probably going to commit that script to that project's codebase. That means it has to be maint…

Many minimal distributions have only the shell installed - which make it (still) relevant for provisioning/bootstrap etc.

Personally I'd much rather maintain a shell script than a perl script - but that's just because I know shell better. Maybe shell is the first language people would program without learning it (js being the second)?

Post reply on HN