In what folllows, it's important to realize that pipe redirection occurs before any other redirections specified by a command.
You can redirect stderror into a pipe thusly:
Code:
$ command="date; twenty-four=24"
$ eval $command 2>&1 | sed 's/^/stdout and stderr from pipe: /'
stdout and stderr from pipe: Wed Apr 21 07:59:39 EDT 2010
stdout and stderr from pipe: -bash: twenty-four=24: command not found
Note, however, that standard output (from the date command) is still going into that pipe as well. If you don't want stdout to go into the pipe, and instead go to whereever stdout was going before the pipe redirection, before executing the eval pipeline, you can save the original, pre-pipe stdout destination in a file descriptor.
Code:
$ exec 3>&1
$ eval $command 2>&1 1>&3 | sed 's/^/stderr from pipe: /'
Wed Apr 21 08:00:13 EDT 2010
stderr from pipe: -bash: twenty-four=24: command not found
Note that the date command's output did not go through sed, but directly to the terminal, in essence, the usual stdout/stderr behavior of a pipe redirection have been flipped.
Also, it's always a good idea to close file descriptors when they're no longer needed (particularly when using an interactive shell or a long-lived shell-script):
Thanks alister for your help.
You already made my day with your help on my other question.
Unfortunately, these fixes do not work.
Actually, stderr is indeed the only redirected.
But the variable assignement doesn't work then.
Code:
toto:~$ one=
toto:~$ command="one=1; twenty-four=24"
toto:~$ eval $command 2>&1 | sed 's/^/stdout and stderr from pipe: /'
stdout and stderr from pipe: -bash: twenty-four=24: command not found
toto:~$ echo $one # (variable not set)
toto:~$ one=
toto:~$ command="one=1; twenty-four=24"
toto:~$ exec 3>&1
toto:~$ eval $command 2>&1 1>&3 | sed 's/^/stderr from pipe: /'
stderr from pipe: -bash: twenty-four=24: command not found
toto:~$ echo $one # (variable not set)
toto:~$ exec 3>&-
That's happening because, due to the presence of the pipe, eval is running in a subshell. $one is properly set, but its value is lost when the subshell exits and control returns to the parent shell.
Code:
$ one=
$ command='one=1; twenty-four=24; echo "one is set to $one"'
$ eval $command 2>&1 | sed 's/^/stdout and stderr from pipe: /'
stdout and stderr from pipe: -bash: twenty-four=24: command not found
stdout and stderr from pipe: one is set to 1
$ echo $one
$ # one is not set here
If you give us a bigger picture of what you are trying to accomplish, perhaps I or someone else can recommend a suitable workaround.
Thanks alister for offering to help.
I thought it would be embarassing to ask for help on an entire project that's why I only posted questions on specific issues.
My whole point is to parse a config file when running my script.
# Read config files...
eval $(while read option value; do
echo "$option=\"$value\""
done)
# Continue with the script...
It roughly works like this but what would happen if the config file contains either mistakes (variable name with dashes) or weird values (path with space)?
If you want the script to abort if there are any invalid variable names in the config (if you try the following, with an invalid variable name in config, in your current shell, it will *poof* disappear , so make sure to do it in a subshell):
Code:
set -e
. config_file
set +e
Or, you could leave "set -e" on, if you like (it causes the shell to terminate when a command fails, with certain exceptions regarding and-or lists and conditionals ... read your shell's 'set' documentation for more info).
As to spaces in a pathname, I don't see how you can detect them since you are using spaces to delimit each path. How is the code to know if the space is embedded in a path or meant to separate one path from another? To be absolutely certain of whether a character is in a path or a delimiter, you would need to select a delimiter that cannot occur in a UNIX path. There is only one such character, the null byte, and it's notoriously difficult to work with in most shells. Perhaps simply checking the validity of each path is sufficient.
Assuming that the config file was sourced as in my example above (using the dot command):
Code:
for p in $PATHS_TO_WATCH; do
if [ ! -d $p ]; then
echo $0: $p: bad path 1>&2
exit 1
fi
done
If an invalid path is encountered, a message (including the script's name and the offending path) is printed to standard error and an exit status of 1 is returned.
Dear all,
I use a pipe command to assign a variable:
$ v_LstStdCdhId=$(cat Bteq_Xport_GetLstStdViewToBuild__1274.txt | grep 'CD/39/AT/CDH_BV_ODS'|cut -d"/" -f1)
$ echo "${v_LstStdCdhId}"
43
49
My aim is to concatenate for each line of the variable v_LstStdCdhId the character "/" in... (3 Replies)
Hi,
I've came across an issue with a script I've been writing to check DHCP addresses on an Solaris system, the script has been running reasonably well, until it hit the following problem:
./sub_mon_v2: redirection error: cannot duplicate fd: Too many open files
./sub_mon_v2: cannot make... (3 Replies)
We use SAP application cluster on AIX. Communication between 2 of its instances is failing randomly with the following error:
java.net.SocketException: There is no process to read data written to a pipe.
The above error causes a cluster restart if an important communication fails.
Can... (0 Replies)
Hi Everyone,
The machine I'm working on is an AIX 5.3 LPAR running on a P650. oslevel -r shows 5300-08. I'm trying to take a backup to a SCSI tape drive, which has been working up until this point. I know of nothing that has changed recently to cause this problem. But when I try to take a... (0 Replies)
Hi.. I am hoping someone could assist me with the pipe program I wrote below. I want to have communication from parent to child and then child to parent.. Is my logic right?
int p,p1;
pipe(p);
pipe(p1);
pid_t pid = fork();
if(pid == 0)
{
close(p);
close(p1);
dup2(p,0);... (1 Reply)
Hi folks :)
Can deamonized process access to stderr, stdout?
I 'm trying to display error_num/return value of a function run() in stderr using
fprintf(stderr, "function run() returns = %d", ret_val);
run() is called after deamonizing the process. (1 Reply)
I have the following code which works on AIX 4.3 but fails at times on AIX 5.3
with:
cat: 0652-054 cannot write to output. There is no process to read data written to a pipe.
validator="${validator_exe} ${validator_parms}"
cmd_line="${CAT} ${data_file} | ${validator}... (6 Replies)
can pipe sychronize thread or process? because I'm trying to create 5 thread or process that can take an integer value and display it. each time a thread display the value, it has to be decrement it by 1 until the value has reach 0. The problem that I'm having is how can that integer value be... (1 Reply)
Herez the question,
In a process which writes into file FILE1 with descriptor
fHandler1 and it is run as a background process
where would statements be directed
when stderr descriptor is used.
fprintf(stderr,"some message\n");
assume that session from which it is run is terminated and... (3 Replies)