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.

If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.

Having a problem logging in? Please visit this page to clear all LQ-related cookies.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

....
If I remove grep command - it works.
If I put ps ax|grep --ignore-case something into script ...
this error appeared again - which is confusing because
grep should use "GNU long options" but NOT "BSD options".

run it in command line in terminal - there is no problem at all. Only in script problem appeared.

Because you did not say what kind of script (shell script? Perl? Python) or even what command you used to run ps ax|grep something in your script, it is very difficult to answer anything meaningful. We need the details!

However..

Pipe | is a shell construct. It looks like your command is not run using a shell, but directly, so that instead of ps ax being run with its output piped to grep something (which is all set up by the shell), you only run ps with parameters ax|grep and something.

A simple way to fix that is to explicitly use a shell to run the command. For example,

This problem did not appear long time before - just after I did some changes in one script of complex of shell /bin/bash scripts.
! BUT I did not change "ps ax|grep -i something" at all in that script !
Weird is that after reboot computer - this error disappeared and everything got into normal and works properly. So, technically I could marked this post as solved but I am very interested how to investigate more deeply - what actually happened and why ?
(I did not have to use "sh -c ..." construct")

You mentioned:
"
...
instead of ps ax being run with its output piped to grep something (which is all set up by the shell), you only run ps with parameters ax|grep and something.
...
"

How can I determinate the way how the shell is going to interpreted command "(parameters or piped in this particular case)" ?
... any help/hint/URLs/doc much appreciate.

So, technically I could marked this post as solved but I am very interested how to investigate more deeply - what actually happened and why ?

I'd need a lot more details -- the exact file, the exact commands, and the exact error messages -- to be confident, but based on the effects and the snippet, I'd say either the su default shell was temporarily changed (by setting the SHELL variable), or the shell options related to parameter expansions had changed.

I am quite confident the error was related to expansion: that instead of being parsed as a shell command line, it was parsed as a single command. In other words, the pipe character (|) was not interpreted by the shell at all. It does not matter at all which commands you had on either side. If the commands did not have any quote characters, then they could not have affected this at all; it would have happened to any command. If you did use quotes, then you might have accidentally quoted the pipe too; perhaps by having unbalanced quotes.

I wouldn't worry about it, though, unless it reoccurs.

The way you have constructed your script is very fragile. In particular,

is not safe; it causes the command line to be re-split if not run as root, with expansions done twice. In other words, it has very different behavior wrt. command line parameters when run as root, than when run as any other user. Dangerous.

In your case, if you could use sudo instead of su, you could use

Code:

#!/bin/bash
if [ "$(id -u)" != "0" ]; then
sudo -- "$0" "$@"
exit $?
fi
# You are now root, do the rest of the stuff...

If you have to use su, then you need to convert the parameters to a single string, which is quite cumbersome. I think this should work, though:

The above constructs a string containing each argument in single quotes into argstring. The only character that should need any escaping is the single quote itself. It cannot be escaped, but you can temporarily switch to double quotes; 'foo'"'"'bar' evaluates to foo'bar . The first argument is of course the path to this script ($0), which needs to be escaped just like the others.

EDIT: Bash built-in printf might actually be a much easier solution for this:

This way you can just unset or clear _log_file to empty string (before this part is executed, of course!), to disable logging. If logging is NOT used, then the script will keep stdout and stderr separate, which is sometimes quite useful.

The logic is as follows:
If we do not have a log file, then the standard error of the work part goes directly to standard error (NOT via the pipe), and standard output to standard output via the pipe and cat.
If we do have a log file, then standard error is merged to standard output in the subshell, so that its standard error is also redirected to the pipe. At the other end of the pipe, teewill duplicate everything to both the log file and to standard output.

Although we use a subshell for both the work and the logging, the execs in the latter replace the subshell with the actual command. Thus, there is only one "extra" subshell, the one doing the work.

Note that you do need to do all work where I added the command. Not only because only that part will be logged, but also because it is a subshell, and any changes it makes to variables or environment will not be visible in the parent shell. Other than that, there should be no quirks to worry about.

Quote:

Originally Posted by masuch

How can I determinate the way how the shell is going to interpreted command

Thanks a lot for this induction to bash scripting - I really appeciate it.
I am slowly implementing your suggestions to many scripts - using combinations of your suggestions.
(I have noticed as well that just in only one case - I had to put command 'ps aux|grep -i "/usr/bin/psensor-server &"' at the begging of the line - if I had some spaces at the begining of the line - it went wrong - do not why.

(--- basicaly it runs script as root with output as on the screen as to the log file (which is my intention).)

--- one part of the script - one function (ps command)
(it is testing if application runs (by pidof and ps) - if not - it is going to start that application
(but I still have some problems to solve - like DBUS_SESSION_BUS_ADDRESS - as you can see :-)