Unix/Linux Go Back    


OS X (Apple) OS X is a line of Unix-based graphical operating systems developed, marketed, and sold by Apple.

Help in explaining this echo conundrum.

OS X (Apple)


Reply    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 03-14-2017
wisecracker's Unix or Linux Image
wisecracker wisecracker is offline
Registered User
 
Join Date: Jan 2013
Last Activity: 22 June 2017, 3:16 PM EDT
Location: Loughborough
Posts: 1,210
Thanks: 364
Thanked 322 Times in 252 Posts
Help in explaining this echo conundrum.

OSX 10.12.3, default bash terminal.
Consider this code and note it is calling 'sh' inside the code...

Code:
#!/bin/sh
echo '1\n2\n2\n3\n5' > /tmp/text
hexdump -C /tmp/text
/bin/echo '1\n2\n3\n4\n5' > /tmp/text
hexdump -C /tmp/text

Now view the interactive mode below, note the underlying shell is bash:-

Code:
Last login: Tue Mar 14 17:12:45 on ttys001
AMIGA:barrywalker~> # Use sh first...
AMIGA:barrywalker~> sh
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:barrywalker~/Desktop/Code/Shell> hexdump -C /tmp/text
00000000  31 0a 32 0a 33 0a 34 0a  35 0a                    |1.2.3.4.5.|
0000000a
AMIGA:barrywalker~/Desktop/Code/Shell> /bin/echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:barrywalker~/Desktop/Code/Shell> hexdump -C /tmp/text
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:barrywalker~/Desktop/Code/Shell> ./echo_test.sh
00000000  31 0a 32 0a 32 0a 33 0a  35 0a                    |1.2.2.3.5.|
0000000a
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:barrywalker~/Desktop/Code/Shell> # Now exit sh...
AMIGA:barrywalker~/Desktop/Code/Shell> exit
exit
AMIGA:barrywalker~> bash -version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:barrywalker~/Desktop/Code/Shell> hexdump -C /tmp/text
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:barrywalker~/Desktop/Code/Shell> /bin/echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:barrywalker~/Desktop/Code/Shell> hexdump -C /tmp/text
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:barrywalker~/Desktop/Code/Shell> ./echo_test.sh
00000000  31 0a 32 0a 32 0a 33 0a  35 0a                    |1.2.2.3.5.|
0000000a
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:barrywalker~/Desktop/Code/Shell> _

1) Why does the 'bash' interactive mode give a different result to the 'sh' mode as 'sh' is merely a subset of 'bash'?
2) Why does echo in 'sh' translate '\n' to newlines in single quotes?
I thought single quotes were to give a raw string of characters, irrespective?
(Is this an Apple OSX thing?)
The 'sh' version is the same as the 'bash' version but are NOT identical files.

TIA...
Sponsored Links
    #2  
Old Unix and Linux 03-14-2017
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 June 2017, 6:44 PM EDT
Location: Saskatchewan
Posts: 22,254
Thanks: 1,105
Thanked 4,197 Times in 3,883 Posts
'echo' is not consistent or portable between different shells. Sometimes you get newlines, sometimes you get \n, sometimes you only get newlines when you ask for them with echo -e, and sometimes you can't get newlines out no matter what you do (i.e. /bin/sh on solaris). Given OSX's nextstep/mach lineage, I'll wild-guess that their /bin/sh is meant to resemble an old Bourne from BSD.

printf is a lot more consistent.
The Following User Says Thank You to Corona688 For This Useful Post:
wisecracker (03-14-2017)
Sponsored Links
    #3  
Old Unix and Linux 03-14-2017
Scrutinizer's Unix or Linux Image
Scrutinizer Scrutinizer is offline Forum Staff  
Moderator
 
Join Date: Nov 2008
Last Activity: 24 June 2017, 3:40 AM EDT
Location: Amsterdam
Posts: 11,451
Thanks: 493
Thanked 3,299 Times in 2,911 Posts
Note that there is a reason that echo is not part of the POSIX specification. For consistent results, it is best to only use printf


Code:
sh-3.2$ /usr/bin/printf '1\n2\n2\n3\n5\n'
1
2
2
3
5
sh-3.2$ printf '1\n2\n2\n3\n5\n'
1
2
2
3
5

I get

Code:
sh-3.2$ echo '1\n2\n3\n4\n5' | od -bc
0000000   061 012 062 012 063 012 064 012 065 012                        
           1  \n   2  \n   3  \n   4  \n   5  \n                        
0000012
sh-3.2$ /bin/echo '1\n2\n3\n4\n5' | od -bc
0000000   061 134 156 062 134 156 063 134 156 064 134 156 065 012        
           1   \   n   2   \   n   3   \   n   4   \   n   5  \n        
0000016

So in the first case \n is interpreted as newline, in the second case it is not.

--
Interestingly:

When I do:
/bin/bash --posix, which is supposed to be the same as /bin/sh I get:


Code:
bash-3.2$ echo '1\n2\n3\n4\n5' | od -bc
0000000   061 134 156 062 134 156 063 134 156 064 134 156 065 012        
           1   \   n   2   \   n   3   \   n   4   \   n   5  \n        
0000016

Also when bash is invoked without the --posix option

On OSX, apparently it is not a link to /bin/bash as is the case on some Linux distributions, but rather they are two distinct binaries

Code:
sh-3.2$ ls -l /bin/sh /bin/bash
-r-xr-xr-x  1 root  wheel  626272 Sep 14 02:57 /bin/bash
-r-xr-xr-x  1 root  wheel  630464 Sep 14 02:57 /bin/sh

If I make a symlink sh -> /bin/bash

Code:
$ ./sh
sh-3.2$ echo '1\n2\n3\n4\n5' | od -bc
0000000   061 134 156 062 134 156 063 134 156 064 134 156 065 012        
           1   \   n   2   \   n   3   \   n   4   \   n   5  \n        
0000016


Last edited by Scrutinizer; 03-14-2017 at 02:08 PM..
The Following User Says Thank You to Scrutinizer For This Useful Post:
wisecracker (03-14-2017)
    #4  
Old Unix and Linux 03-14-2017
wisecracker's Unix or Linux Image
wisecracker wisecracker is offline
Registered User
 
Join Date: Jan 2013
Last Activity: 22 June 2017, 3:16 PM EDT
Location: Loughborough
Posts: 1,210
Thanks: 364
Thanked 322 Times in 252 Posts
@ Scrutinizer...

Also interestingly when using 'dash' on OSX 10.12.3 default bash terminal:-

Code:
Last login: Tue Mar 14 18:32:20 on ttys000
AMIGA:amiga~> /usr/local/bin/dash
AMIGA:\u\w> echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:\u\w> hexdump -C /tmp/text
00000000  31 0a 32 0a 33 0a 34 0a  35 0a                    |1.2.3.4.5.|
0000000a
AMIGA:\u\w> /bin/echo '1\n2\n3\n4\n5' > /tmp/text
AMIGA:\u\w> hexdump -C /tmp/text
00000000  31 5c 6e 32 5c 6e 33 5c  6e 34 5c 6e 35 0a        |1\n2\n3\n4\n5.|
0000000e
AMIGA:\u\w> exit
AMIGA:amiga~> _

Seems consistent with 'sh'.
I am going to have to be careful with this.

---------- Post updated at 07:39 PM ---------- Previous update was at 07:10 PM ----------

Quote:
Originally Posted by Corona688 View Post
'echo' is not consistent or portable between different shells. Sometimes you get newlines, sometimes you get \n, sometimes you only get newlines when you ask for them with echo -e, and sometimes you can't get newlines out no matter what you do (i.e. /bin/sh on solaris). Given OSX's nextstep/mach lineage, I'll wild-guess that their /bin/sh is meant to resemble an old Bourne from BSD.

printf is a lot more consistent.
I do know a few ideas but do not know if this would work in the Solaris situation you quoted.
This is longhand using 'dash' and '/bin/echo'...
You will have to take my word for the 'bold' as it does not copy and paste too well... ;o)

Code:
Last login: Tue Mar 14 19:22:37 on ttys000
AMIGA:amiga~> /usr/local/bin/dash
AMIGA:\u\w> nl='
> '
AMIGA:\u\w> esc=`printf "\033"`
AMIGA:\u\w> /bin/echo '1\n2\n3'
1\n2\n3
AMIGA:\u\w> /bin/echo "1\n2\n3"
1\n2\n3
AMIGA:\u\w> /bin/echo '1${nl}2${nl}3'
1${nl}2${nl}3
AMIGA:\u\w> /bin/echo "1${nl}2${nl}3"
1
2
3
AMIGA:\u\w> # Make characters BOLD...
AMIGA:\u\w> /bin/echo "Normal text, $esc[1mbold text..."
Normal text, bold text...
AMIGA:\u\w> exit
AMIGA:amiga~> _

There are ways to bend rules even in dash...

Last edited by wisecracker; 03-14-2017 at 03:43 PM.. Reason: Sorry about the attachment. I did expect a new window.
Sponsored Links
    #5  
Old Unix and Linux 03-15-2017
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 June 2017, 6:44 PM EDT
Location: Saskatchewan
Posts: 22,254
Thanks: 1,105
Thanked 4,197 Times in 3,883 Posts
Quote:
Originally Posted by wisecracker View Post
Seems consistent with 'sh'.
I am going to have to be careful with this.
Basically, only use echo if you want to print preformatted / unescaped data: Any extended behavior like processing backslashes isn't portable.

Quote:
I do know a few ideas but do not know if this would work in the Solaris situation you quoted.
I don't see any point fighting it when there's better alternatives though. Your solution is twice as complicated and much less efficient than just using printf once to do both jobs.
printf "\033[1mBold Text\033[0m Normal Text\n"

You're not breaking the rules, though Linux It's completely fine to store any ASCII character besides NULL in a variable.

Last edited by Corona688; 03-15-2017 at 11:45 AM..
Sponsored Links
    #6  
Old Unix and Linux 03-16-2017
wisecracker's Unix or Linux Image
wisecracker wisecracker is offline
Registered User
 
Join Date: Jan 2013
Last Activity: 22 June 2017, 3:16 PM EDT
Location: Loughborough
Posts: 1,210
Thanks: 364
Thanked 322 Times in 252 Posts
Hi Corona688...
Quote:
I don't see any point fighting it when there's better alternatives though. Your solution is twice as complicated and much less efficient than just using printf once to do both jobs.
Perhaps but my non-rooted Android phone does NOT have printf it only has the same as my echo but the terminal I have on it does emulate the escape codes and the shell resembles a cut down version of bash, probably 'bash --posix' as I can only call it as 'sh'. Hence my experiments with 'echo' over a period of time.
Sponsored Links
    #7  
Old Unix and Linux 03-17-2017
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 June 2017, 6:44 PM EDT
Location: Saskatchewan
Posts: 22,254
Thanks: 1,105
Thanked 4,197 Times in 3,883 Posts
Quote:
Originally Posted by wisecracker View Post
Hi Corona688...

Perhaps but my non-rooted Android phone does NOT have printf
Then it's not actually a Bourne shell, and your efforts to be portable with it will be in vain.

If it's not rooted, you're using some weird imitation cooked up in Java and likely don't even have a terminal.

Last edited by Corona688; 03-17-2017 at 12:01 PM..
Sponsored Links
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Help to explaining a command in run dot tcl mar85 Shell Programming and Scripting 6 12-09-2012 07:44 PM
umask conundrum Irishboy24 UNIX for Dummies Questions & Answers 1 07-11-2012 01:52 PM
Explaining some lines from files : .login and .cshrc bbqtoss UNIX for Dummies Questions & Answers 5 01-13-2012 08:00 AM
Need help explaining how to use a VPN on a UNIX server with a Mac OS psycopuppy UNIX for Dummies Questions & Answers 0 05-02-2011 11:18 PM
explaining awk phone_book UNIX for Dummies Questions & Answers 1 03-21-2009 08:38 AM



All times are GMT -4. The time now is 06:35 AM.