How to use pipe operator as simple character in text file?

Hello all, I have two files which are cmd and disk.

`$cat cmd  
lsdev | grep -iw`  
`$cat disk  
hdisk2`  

Now I want to use the contents of both the files in a way such that

`lsdev | grep -iw`

command works for hdisk2 when I write the following script:

`!#/bin/sh  
cmd1="$( sed -n '1p' cmd)"  
disk1="$ (sed -n '1p' disk)"  
comm="$cmd1 $disk1"`
echo `$comm`

Now whenever I try to run the script, an error is thrown regarding wrong usage of | in lsdev command. Please help me find a solution for the same. Thanx

You have single quote within double quote, does not work. cmd1="$( sed -n '1p' cmd)"

Space after the $ gives problem disk1="$ (sed -n '1p' disk)"
This have one back ticks not two comm="$cmd1 $disk1"`

Well, I will try your suggested answer in a while but have got a similar problem as well:

[root@SVHJ1315 SCRIPTING]# cat cmd
cat -n reduce_opt.sh "|" grep -iw
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# cat file
echo
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# cat command1 
#!/bin/sh

one=$(sed -n '1p' cmd)
two=$(sed -n '1p' file)
both=`echo $one $two`
echo `$both`
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# ls -lrt command1 
-rwxr-xr-x. 1 root root 94 Mar  2 20:58 command1
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# sh command1 
cat: invalid option -- 'i'
Try `cat --help' for more information.

[root@SVHJ1315 SCRIPTING]# 
[root@SVHJ1315 SCRIPTING]# 

There's nothing wrong with that syntax. Within that command substitution, the use of single or double quotes is nothing special, even if the command substitution itself is double quoted. The only effect of double-quoting an entire subsitution is that the result of the command is protected from field-splitting and filename globbing (neither of which would happen here anyway, since operations that may yield multiple fields are not performed when assigning to a variable).

From POSIX: Shell Command Language:

The same cannot be said of the older though still widely-used backtick style, ` ... ` . In my opinion, that is a very persuasive reason to never use it. The backtick version can get hairy, particularly with nesting or quoting or, or (I hesitate to even contemplate the possibility) nested quoting.

Regards,
Alister

---------- Post updated at 11:49 AM ---------- Previous update was at 11:33 AM ----------

The error is occurring because the pipe character in $comm is not treated specially. The shell command parsing step which interprets the pipe symbol as a special character has completed by the time the shell expands the variable containinig the pipe. For your approach to work, you'd need to use eval to pass the value of $comm (or $both, in your second example) through the shell parser. This has security implications, so if you are not familiar with eval , you should do some research.

Nothing that you've mentioned suggests you need to resort to eval . Aside from security issues, it can be a pain to protect metacharacters from the effects of going through the shell parser more than once. It would be simpler and much more secure and robust to simply parameterize your script so that the grep pattern can be a simple argument.

Regards,
Alister

To be honest i don't understand what you intend the sed's to do. What they actually do is to reduce the file to its first line. A "head -1" would do the same, no?

Further, there is a problem when you try to expand variables which contain blanks, because blanks are special to the shell: they separate "fields", individual parts of the input line. I will show this in an example, which actually happened in a shipped version of AIX (see the full story here):

First a word of caution: create a separate directory for this to try it out, you will see why.

Suppose you want to redirect the output of a process to a file and you want to be flexible about it, so you put it into a variable: instead of

command > file

you write in your script:

destination="file"
command > "$destination"

This will work perfectly and as expected. (When you try this replace "command" with any UNIX command - "ls -l" will do, for instance.) But now suppose you want to include the error channel in your redirect too and you do it this way:

destination="file 2>&1"
command > "$destination"

What will happen? For the shell, the content of "$destination" is one word and it will redirect only the <stdout> - [i]but to a file named "file 2>&1". (This is why i told you to create a separate directory for this - you can easily remove this directory instead of having to find out how to delete files with special characters.)

How this might function? There are two possible solutions: first, create your variables so that the blanks are outside:

dest_out="file"
dest_err="&1"
command > "$dest_out" 2>"$dest_err"

Second possibility: use "eval". The reason why the shell has problems is that it parses the lines in a fixed procedure. When variables are expanded, they are all expanded together and no second pass is given to them (this is why it isn't possible to have a variable point to another variable with "normal" means). But "eval" restarts this evaluation process and this makes the shell "reconsider" the line with the now expanded blanks in it:

destination="file 2>&1"
eval command > "$destination"

Btw.: you should really REALLY stay away from the backticks. They are only supported for backwards compatibility reasons and their use is discouraged. Only use the subshell "$(...)".

I hope this helps.

bakunin