bash/sh: global or local variable with for (loop) isssue
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
every pipe creates a subshell and that's why nothing you assign to a variable after a pipe is visible outside. It's a common mistake: A variable can't be exported from a subshell to the parent shell.
Your script works fine if you replace /bin/bash by /bin/ksh or /bin/zsh.
In my opinion, bash developers took an unfortunate decision when choosing which part of a pipeline would be run in a subshell.
In my opinion, bash developers took an unfortunate decision when choosing which part of a pipeline would be run in a subshell.
Not so much the decision where to start the subshell is bad (*nix contains more very rigid orthogonalities which you have to learn to live with, either good or bad) but incompatibility between the shells is disastrous in my opinion. It doesn't only mean that this script runs the way it is intended in other shells while not in bash, it also means that scripts which run in bash using this property may crash or give unintentional results in other shells.
As for this particular script, I don't see the use for piping. I have seen a few of this similar problems over the past few months which all concerned piping into a loop. Piping the result of one program into another (like
Code:
cat myfile | grep foo | sed s/foo/bar/g
is logical and harmless. Piping into a loop
Code:
ls -1 | while read .... done
might be syntactically correct and executable, it still is not elegant programming. It is awkward to have one statement producing one result, and feed that into a repetitive loop using a part of that result bit by bit, without you are clearly aware of doing that. This is clearly different from, for example, producing a string and parse it by token in the next loop.
The example chrism01 provided is much cleaner, provides hooks for debugging and makes the code obvious and understandable. Maybe programmers should be discouraged of using pipes in this manner anyway.
Not so much the decision where to start the subshell is bad (*nix contains more very rigid orthogonalities which you have to learn to live with, either good or bad) but incompatibility between the shells is disastrous in my opinion.
These are different points.
Either you explicitely specify the shell you use (bash, ksh, zsh, whatever) and you are free to take advantage of their specific enhancements.
Either you want to write portable scripts and you need to stick to POSIX shell statements and syntax.
What is unfortunate in that specific pipe subshell case is POSIX didn't choose to follow ksh (which was the model for most features) and let that choice implementation dependent. Scripts that rely on variable sets in pipeline components are thus all non portable.
Quote:
It doesn't only mean that this script runs the way it is intended in other shells while not in bash, it also means that scripts which run in bash using this property may crash or give unintentional results in other shells.
True, but the interpreter should be specified to avoid the risk.
Quote:
As for this particular script, I don't see the use for piping.
Yes. I just pointed it as an example.
Quote:
I have seen a few of this similar problems over the past few months which all concerned piping into a loop. Piping the result of one program into another (like
Code:
cat myfile | grep foo | sed s/foo/bar/g
is logical and harmless.
Harmless but far to be optimized. Both cat and grep are unnecessary:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.