4 ms·
The UNIX shell was designed for, and makes sense in, a friendly, collaborative environment. "This breaks for filenames with spaces." "Well then don't do that.
by username223 11y ago
The UNIX shell was designed for, and makes sense in, a friendly, collaborative environment. "This breaks for filenames with spaces." "Well then don't do that. If punching yourself in the face hurts, then stop doing it." Feeding malicious input to programs on your own computer is self-destructive, and UNIX's creators felt no need to defend against it. It's "an elegant weapon for a more civilized age."
Nowadays, even trying to read a page of "hyper-text" requires doing battle with several levels of malicious software.
- GFK_of_xmaspast 11y agoIn other words, it breaks as soon as you look at it funny, and the users get blamed.
- username223 11y agoNo. Imagine, if you can, a world in which programs are things designed to help their authors/users, not adversaries to be exploited or defeated.
- oblio 11y agoSo Utopia? Also, see Neverland. We can imagine that world, but does it really help professionals in any way if they do imagine it?
- thristian 11y agoNot at all. That world existed, for the brief interval between 'only people who have access to a computer are people who devoted their careers to it' and 'everybody who can afford $50 a month has access to the Internet'. In that time, only a few people had access to computing and network resources, but they were all well-educated, reasonably well-paid and curious, with lots of motivation to help each other out and little motivation to undermine each other. It might have remained just a brief blip of history, except that so many technologies developed during that time, designed with the security assumptions of that time (i.e. practically none), became the fundamental underpinnings of our modern world, like MS-DOS and Unix.
- _0ffh 11y agoThis, so much this! It's amazing how fast you can go from "that guy with the curious hobby" to "some guy that naturally also owns and uses a computer, as everyone else does".
- GFK_of_xmaspast 11y agoI didn't start using unix/vms systems until the early 90s in college, which was at least a couple years before your "$50/month access to the internet", if we count aol and compuserve, and by that time it was most certainly the case that the era of "[the] only people who have access to a computer are people who devoted their careers to it" was long since passed.
- rawdisk 11y agoBeautiful. When something better comes along I'll switch away from using the UNIX shell. But I am not sure I'll live long enough to see that day. Meanwhile I am too busy using the shell to engage in that battle with hypertext. It could just be my perception, but after years of practice, I think I am winning.
- simoncion 11y ago> This breaks for filenames with spaces. Useful things in bash: export IFS=$'\n' or export IFS=$'\n' for I in `$COMMAND` do $OTHER_COMMAND "${I}" done or, generally: find ./ -print0 | xargs -0 $COMMAND
- pdkl95 11y ago> export IFS Be careful exporting a changed IFS. That will inherit into child commands, which can cause unexpected breakage. A better model is to simply set IFS in the bash script (without export) or even better, as a one-off prefix to a command # leaves IFS set for following commands IFS=$'\n' $COMMAND # only sets IFS for one command IFS=$'\n' $COMMAND It is common to see saving/restoring IFS to protect against bugs elsewhere from a non-standard IFS: oldIFS="$IFS" IFS=$'\n' # ...stuff... IFS="$oldIFS" If you do this, a trap is a better idea to guarantee the restore happens. Better yet, let bash handle that for you automagically by using a local variable. cmd_with_nonstandard_ifs() { local IFS='\n' $COMMAND } cmd_with_nonstandard_ifs # IFS is back to normal here Also, unless you're using a really ancient version of bash, you shouldn't use backticks for command substitution. Use $() instead. # backticks need to be escaped when nested FOO="`basename "\`command_that_outputs_a_path\`"`" # much easier to read in the modern form FOO="$(basename "$(command_that_outputs_a_path)")" The thing is, you probably don't even need mess with IFS - shell globbing handles a lot of these things for you $ ls -1 a bc a b c d e ddd eee $ for file in * ; do echo "[$file]" ; done [a bc] [a b c d e] [ddd eee] and arguments be expanded correctly with "$@" show_args() { for arg in "$@" ; do echo "arg that supports spaces: [$arg]" done } show_args "foo bar" > find | xargs Of course, this is always a nice option that bypasses the need for bash. Minor suggestion: "find ." and "find ./" are identical.
- simoncion 11y agoAll good advice. I was intentionally making a correctness/terseness tradeoff. :) > ...and arguments be expanded correctly with "$@" That assumes that your bash is contained within a script, yes? It doesn't work for commands entered directly in a shell? > ...unless you're using a really ancient version of bash, you shouldn't use backticks for command substitution. I was -stupidly- unaware that backticks would nest. I always use $() when I want to nest command substitutions. > "find ." and "find ./" are identical. Oh, I know. I have the largely unjustifiable habit of always putting a path in a find invocation, as well as always spelling "the current directory" as ./ > > find | xargs > Of course, this is always a nice option that bypasses the need for bash. Don't forget -print0 and -0 if you expect to have to handle arguments that contain spaces! ;)