Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Sat, 11 Jan 2003 05:58:50



I'm working on a bourne shell utility script that reads
a bourne shell script, modifies then outputs it.
Obviously, there're problems inherent in that process.
I've managed to avoid read's destruction of the input
when it encounters a backslash, but now I'm stuck at the
output. (Read on before you suggest an answer :-)

One criteria is that whatever command or utility I use
must work in plain, vanilla bourne shell and must be a
VERY common utility (sed, awk, etc.). Portability
across platforms is critical (Solaris, HP-UX, AIX,
Linux) and assuming that anything but the bare minimum
installation is in place would be trouble.

printf works great, but may not be available. So far,
my attempts to get awk to do the job have not been
pretty (I can't seem to get the quoting right to pass
the string as-is to awk). Here's an example line that
causes problems:
_ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && ECHO="echo -e"

As you can see, the presence of \n as well as single and
double quotes makes it tricky. All I want to do is output
it to a file as-is, but... (I can't process the line to
add backslashes since that usually involves echo-ing it
through sed or somesuch and echo would corrupt the line.)

Any suggestions? Tricks? I could include a small utility
with the script, one for each target platform, if I had
to as long as there were no legal restrictions on its
distribution (it wouldn't be part of our product, just
a necessary helper). -Wm

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by William Par » Sat, 11 Jan 2003 06:32:53



> I'm working on a bourne shell utility script that reads
> a bourne shell script, modifies then outputs it.
> Obviously, there're problems inherent in that process.
> I've managed to avoid read's destruction of the input
> when it encounters a backslash, but now I'm stuck at the
> output. (Read on before you suggest an answer :-)

> One criteria is that whatever command or utility I use
> must work in plain, vanilla bourne shell and must be a
> VERY common utility (sed, awk, etc.). Portability
> across platforms is critical (Solaris, HP-UX, AIX,
> Linux) and assuming that anything but the bare minimum
> installation is in place would be trouble.

> printf works great, but may not be available. So far,
> my attempts to get awk to do the job have not been
> pretty (I can't seem to get the quoting right to pass
> the string as-is to awk). Here's an example line that
> causes problems:
> _ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && ECHO="echo -e"

'read -r' will read it unmodified.  (tested and confirmed).

--

Linux solution for data management and processing.

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Stephane CHAZELA » Sat, 11 Jan 2003 06:41:32


Not sure I understood what you wanted but to safely and portably
print a string (with an additional linefeed), there's

cat << EOS
$string
EOS

or

expr "x$string" : 'x\(.*\)'

To print a string without an additional linefeed, provided the
string doesn't contain linefeeds itself, you can add a "| tr -d
\\12"

awk 'END{printf("%s", string)}' string="$string" < /dev/null

might be portable enough.

--
Stphane

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by those who know me have no need of my nam » Sat, 11 Jan 2003 07:04:57


in comp.unix.shell i read:


>> _ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && ECHO="echo -e"

>'read -r' will read it unmodified.  (tested and confirmed).

on a vanilla bourne shell?

--
bringing you boring signatures for 17 years

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Robert Heuse » Sat, 11 Jan 2003 07:04:25



> Not sure I understood what you wanted but to safely and portably
> print a string (with an additional linefeed), there's

> cat << EOS
> $string
> EOS

> or

> expr "x$string" : 'x\(.*\)'

> To print a string without an additional linefeed, provided the
> string doesn't contain linefeeds itself, you can add a "| tr -d
> \\12"

> awk 'END{printf("%s", string)}' string="$string" < /dev/null

> might be portable enough.

Are you sure, your solutions will output a file like

foo\bar
next\net
something\\more

_including_ all the backslashes as they are (ie: _unchanged_)?

That was OP's main point: process a file through $YET_TO_BE_DEFINED_TOOL
  doing some clever things but maintain the specials (quotes, backticks,
dollars, backslashes, you name it, they've got it).

cheers
robert

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Sat, 11 Jan 2003 07:26:05



Quote:> Not sure I understood what you wanted but to safely and portably
> print a string (with an additional linefeed), there's

> cat << EOS
> $string
> EOS

Do'h! After all my head scratching, it never occured to me
to use cat and a here document to solve the problem. Looks
like that does the trick.

Testing my "bad boy" line:
 Input: _ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && _ECHO="echo -e"
Output: _ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && _ECHO="echo -e"

Huzzah!

Thanks! -Wm

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by bd » Sat, 11 Jan 2003 10:47:38



> I'm working on a bourne shell utility script that reads
> a bourne shell script, modifies then outputs it.
> Obviously, there're problems inherent in that process.
> I've managed to avoid read's destruction of the input
> when it encounters a backslash, but now I'm stuck at the
> output. (Read on before you suggest an answer :-)

> One criteria is that whatever command or utility I use
> must work in plain, vanilla bourne shell and must be a
> VERY common utility (sed, awk, etc.). Portability
> across platforms is critical (Solaris, HP-UX, AIX,
> Linux) and assuming that anything but the bare minimum
> installation is in place would be trouble.

> printf works great, but may not be available. So far,
> my attempts to get awk to do the job have not been
> pretty (I can't seem to get the quoting right to pass
> the string as-is to awk). Here's an example line that
> causes problems:
> _ECHO='echo' ; [ "x`echo \"\n\"`" = 'x\n' ] && ECHO="echo -e"

> As you can see, the presence of \n as well as single and
> double quotes makes it tricky. All I want to do is output
> it to a file as-is, but... (I can't process the line to
> add backslashes since that usually involves echo-ing it
> through sed or somesuch and echo would corrupt the line.)

> Any suggestions? Tricks? I could include a small utility
> with the script, one for each target platform, if I had
> to as long as there were no legal restrictions on its
> distribution (it wouldn't be part of our product, just
> a necessary helper). -Wm

Why not:
#include <stdio.h>
int main(int argc, char *argv[]){
        int i;
        for(i = 1; i<argc;i++)
                printf("%s",argv[i]);
        return 0;

Quote:}

Example usage:
./stupidecho 'Hello\n' "\n"
Will echo:
Hello\n

Also, echo -E may work. Or:
cat << EOF
Hello\n
EOF

--
Replace spamtrap with bd to reply.
"They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety."
                -- Benjamin Franklin, 1759

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by those who know me have no need of my nam » Sat, 11 Jan 2003 12:47:10


in comp.unix.shell i read:


>> One criteria is that whatever command or utility I use
>> must work in plain, vanilla bourne shell and must be a
>> VERY common utility (sed, awk, etc.). Portability
>> across platforms is critical (Solaris, HP-UX, AIX,
>> Linux) and assuming that anything but the bare minimum
>> installation is in place would be trouble.
>Why not:

[snip a c program]

not all systems provide c compilers.

Quote:>cat << EOF
>Hello\n
>EOF

no need for the `\n'.

--
bringing you boring signatures for 17 years

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by bd » Sun, 12 Jan 2003 06:42:46



> in comp.unix.shell i read:

>>> One criteria is that whatever command or utility I use
>>> must work in plain, vanilla bourne shell and must be a
>>> VERY common utility (sed, awk, etc.). Portability
>>> across platforms is critical (Solaris, HP-UX, AIX,
>>> Linux) and assuming that anything but the bare minimum
>>> installation is in place would be trouble.

>>Why not:
> [snip a c program]

> not all systems provide c compilers.

>>cat << EOF
>>Hello\n
>>EOF

> no need for the `\n'.

That was to demonstrate it wouldn't expand it.
--
Replace spamtrap with bd to reply.
Your good nature will bring unbounded happiness.
 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by those who know me have no need of my nam » Sun, 12 Jan 2003 07:17:20


in comp.unix.shell i read:


>> in comp.unix.shell i read:
>>>cat << EOF
>>>Hello\n
>>>EOF

>> no need for the `\n'.

>That was to demonstrate it wouldn't expand it.

ahh, right.  that was one of the needs.  sorry.

--
bringing you boring signatures for 17 years

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Mon, 13 Jan 2003 05:23:31



Quote:

> Why not:
> #include <stdio.h>
> int main(int argc, char *argv[]){
>         int i;
>         for(i = 1; i<argc;i++)
>                 printf("%s",argv[i]);
>         return 0;
> }

I'd considered that. (Actually, if I went that route,
I'd incorporate a few other simple string tasks into
it.) We'd have to pre-compile the utility and stash it
on our distribution disk, but we already do that for
another one, so it is feasible.

My main reasons for doing it in bourne shell are:
   1. It's more painful (well, OK, it's a growth
      experience and a learning exercise).
   2. Ease of maintenance (anyone with a text editor
      can muck around with it).
   3. It can easily interface with or be incorporated
      into our other scripts as needed. (One file to
      copy/include rather than a script plus one or
      more OS-dependant utilities.)

It's quite possible that I'll just rewrite the whole
thing in C eventually, but I've got to tell you, figuring
out the bourne shell tricks needed to make it work has
been fun. (Though "nailing jelly to a tree" describes
a large part of the process.) -Wm

 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Mon, 13 Jan 2003 07:14:06




> > Not sure I understood what you wanted but to safely and portably
> > print a string (with an additional linefeed), there's

> > cat << EOS
> > $string
> > EOS

[...]
> Are you sure, your solutions will output a file like

> foo\bar
> next\net
> something\\more

> _including_ all the backslashes as they are (ie: _unchanged_)?

> That was OP's main point: process a file through $YET_TO_BE_DEFINED_TOOL
>   doing some clever things but maintain the specials (quotes, backticks,
> dollars, backslashes, you name it, they've got it).

So far cat does the trick. The first major test was passing
the filter script through itself then running the result.
Worked. (I was holding my breath.) Here's a sample function
that passes through it successfully (not pretty, but...):

PP_ParseFile ()
{
 if [ -f "$1" ] ; then
  PP_CURFILE="$1"
  PP_USEREND=0
  PP_LINECNT=0
  [ $PP_CFD -lt 8 ] || PP_ErrorExit "File descriptor allowance exceeded."
  PP_IncVar PP_CFD
  $PP_SED "$PP_NOSPACE"'s/\\/&&/g' "$1" > "$PP_TMPDIR/${1}.pptf.$PP_CFD"
  eval "exec $PP_CFD<'$PP_TMPDIR/${1}.pptf.$PP_CFD'"
  eval 'while IFS= read PP_RAW 0<&'"$PP_CFD"'
  do
   IFS="$PP_IFS"
   $PP_CNTLNS
   case "${PP_NOBLANKS}${PP_IFSKIP}${PP_KEEPCOMS}$PP_RAW" in
    1?? ) ;;
    0?? ) PP_PrintVal "$PP_RAW" "$PP_OUTFILE" ;;
    *\#* )
     set -- $PP_RAW
     case "${PP_IFSKIP}${PP_KEEPCOMS}$1" in
      ??\#[a-z]* ) PP_ParseLine "$1" "$PP_RAW" || break ;;
      00\#* )  ;;
      0?* ) PP_PrintVal "$PP_RAW" "$PP_OUTFILE" ;;
      * ) ;;
     esac
     ;;
    ?0* ) PP_PrintVal "$PP_RAW" "$PP_OUTFILE" ;;
   esac
  done'
  IFS="$PP_IFS"
  eval "exec $PP_CFD<&-"
  PP_DecVar PP_CFD
  [ "0$PP_USEREND" -eq 0 -a -n "$PP_IFSTK" ] && PP_ErrorExit "Missing
#endif"
  return 0
 fi
 return 1

Quote:}

BTW, the PP_PrintVal function contains the cat << EOS stuff.
-Wm
 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Fri, 17 Jan 2003 02:14:17




> > Not sure I understood what you wanted but to safely and portably
> > print a string (with an additional linefeed), there's

> > cat << EOS
> > $string
> > EOS

Just in case anyone else can use it, here's what I
finally came up with. I started with Robert's suggestion,
but needed a little additional processing, so I used sed
instead (bourne shell):

#----------------------------------------------------------------
# Prints the value without any interpretation. A destination file
# can be spcified, otherwise it goes to stdout. If the
# substitutions argument has sed-type patterns in it (s/xxx/yyy/),
# those are applied before the value is output.
PrintVal () # value [substitutions [destfile]]
{
    eval sed "${2:+-e '$2'}"' <<- EOV '"${3:+>>'$3'}"'
$1
EOV'

Quote:}

Note: The first line extends from eval to $3'}"', ignore any
spurious wrapping within it. The $1 and EOV are against the
left margin (though they can be indented with tabs if you
want thanks to the '-' in '<<-'). -Wm
 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Fri, 17 Jan 2003 04:37:51



[Correction:]

Quote:> PrintVal () # value [substitutions [destfile]]
> {
>     eval sed -n "${2:+-e '$2'} -e 'p' <<- EOV ${3:+>>'$3'}"'
> $1
> EOV'
> }

The previous version worked IF there was a substitution
string, but not otherwise - just didn't print anything. -Wm
 
 
 

Looking for a brain-dead echo - i.e., an echo-like command that will pass \n

Post by Willia » Fri, 17 Jan 2003 07:15:53


Yet another tweak (it's a work in progress, what can I
say):

PrintVal () # value [substitutions [destfile]]
{
    eval sed -n "${2:+-e '$2'} -e 'p' <<- EOV ${3:+>>'$3'}"'
$1
EOV
' # <-- Put the closing quote on its own line

Quote:}

Without that change it worked on Solaris, but not
under cygwin's shell (and, presumably others). The
same problem occured with backticks. I assume it
has to do with the EOL being inside or outside the
quotes and some shells caring about it. -Wm
 
 
 

1. diff among echo a>f; command<f; echo $a|command; command << $a; EOF

What is the difference among:

1)
echo $passwd > file
command < file

2)
echo $passwd | command

3)
command << EOF
$passwd
EOF

To me they are all equivalent ( I am talking about functionality, not
UUOC stuff here ). But the DBA claims that only 1) works for the oracle
financial application applmgr, and it beats me. 1) is recommended by oracle
on the manual but I prefer 2 and 3. Please shed some light on
the issue. Thanks.
--
Michael Wang
http://www.mindspring.com/~mwang

2. Changing from UMSDOS to Linux partition w/swap partition?

3. echo $$ ; (echo $$)

4. Problems with a Tatung 1624E CD-ROM

5. ICMP echo and port 7 echo service

6. UNIX Network Programming, V2

7. Local Echo vs Host Echo for tty's

8. The tale of the changing password

9. Linux 1.2.13: echo echoes \n

10. what causes kdm to echo "*" vs. no echo for password

11. Q: What echoes faster than /bin/echo?

12. no echo when there should be echo

13. telnet echo on/off causes strange crlf echo