#] #] ********************* #] "$d_SysMaint"'Linux/echo notes.txt' - ??? # www.BillHowell.ca 17Feb2023 initial # view in text editor, using constant-width font (eg courier), tabWidth = 3 #48************************************************48 #24************************24 # Table of Contents, generate with : # $ grep "^#]" "$d_SysMaint"'Linux/echo notes.txt' | sed "s/^#\]/ /" # #24************************24 #] Setup, ToDos, #] 02Aug2023 function returns via multiple echos https://stackoverflow.com/questions/17336915/return-value-in-a-bash-function What's annoying is that a function that should provide data cannot also echo other stuff to stdout, because the caller using $() will receive that too and get confused or have to parse the output. Global variables are not great because it's just a matter of time before you use the same global var in two places that happen to be nested and data could get lost. There should be separate channels for printing data vs sending data back. – Oliver Aug 2, >> I can use this for structured data returns #] 02Aug2023 Dynamic scoping means that ret_val points to a different object, #] depending on the caller! This is different from lexical scoping, #] which is what most programming languages use. #] +-----+ #24************************24 #08********08 #] ??Aug2023 #08********08 #] ??Aug2023 #08********08 #] ??Aug2023 #08********08 #] 02Aug2023 search "Linux function returns and echo" +-----+ https://stackoverflow.com/questions/17336915/return-value-in-a-bash-function Return value in a Bash function Asked 10 years, 1 month ago Modified 1 year, 2 months ago Viewed 691k times I am working with a bash script and I want to execute a function to print a return value: function fun1(){ return 34 } function fun2(){ local res=$(fun1) echo $res } When I execute fun2, it does not print "34". Why is this the case? bashfunctionreturn-value edited Apr 11, 2018 at 21:45 learningbee asked Jun 27, 2013 at 7:17 mindia +--+ Although Bash has a return statement, the only thing you can specify with it is the function's own exit status (a value between 0 and 255, 0 meaning "success"). So return is not what you want. You might want to convert your return statement to an echo statement - that way your function output could be captured using $() braces, which seems to be exactly what you want. ... edited Mar 16, 2021 at 16:08 Peter Mortensen answered Jun 27, 2013 at 7:19 tamasgal +--+ What's annoying is that a function that should provide data cannot also echo other stuff to stdout, because the caller using $() will receive that too and get confused or have to parse the output. Global variables are not great because it's just a matter of time before you use the same global var in two places that happen to be nested and data could get lost. There should be separate channels for printing data vs sending data back. – Oliver Aug 2, +--+ The problem with other answers is they either use a global, which can be overwritten when several functions are in a call chain, or echo which means your function cannot output diagnostic information (you will forget your function does this and the "result", i.e. return value, will contain more information than your caller expects, leading to weird bugs), or eval which is way too heavy and hacky. The proper way to do this is to put the top level stuff in a function and use a local with Bash's dynamic scoping rule. Example: func1() { ret_val=hi } func2() { ret_val=bye } func3() { local ret_val=nothing echo $ret_val func1 echo $ret_val func2 echo $ret_val } func3 This outputs nothing hi bye Dynamic scoping means that ret_val points to a different object, depending on the caller! This is different from lexical scoping, which is what most programming languages use. This is actually a documented feature, just easy to miss, and not very well explained. Here is the documentation for it (emphasis is mine): Variables local to the function may be declared with the local builtin. These variables are visible only to the function and the commands it invokes. For someone with a C, C++, Python, Java,C#, or JavaScript background, this is probably the biggest hurdle: functions in bash are not functions, they are commands, and behave as such: they can output to stdout/stderr, they can pipe in/out, and they can return an exit code. Basically, there isn't any difference between defining a command in a script and creating an executable that can be called from the command line. So instead of writing your script like this: Top-level code Bunch of functions More top-level code write it like this: # Define your main, containing all top-level code main() Bunch of functions # Call main main where main() declares ret_val as local and all other functions return values via ret_val. See also the Unix & Linux question Scope of Local Variables in Shell Functions. Another, perhaps even better solution depending on situation, is the one posted by ya.teck which uses local -n. edited Mar 16, 2021 at 17:55 Peter Mortensen Oliver's user avatar Oliver #08********08 #] 28Jul2023 how to echo a line feed , other backslash chrs: echo $'hello\nworld' +-----+ https://stackoverflow.com/questions/8467424/echo-newline-in-bash-prints-literal-n echo $'hello\nworld' prints hello world $'' strings use ANSI C Quoting: Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. edited Mar 12, 2015 at 15:19 Rory O'Kane answered Nov 2, 2012 at 9:39 Vanuan #08********08 #] 17Feb2023 search 'Linux echo and why does it remove tabs?' -> use read then echo "$d_bin"'fileops calls.sh' pinn_strOld_strNew_replace 1 "$d_web"'webWork files/fin footer Paul Vauhan.html' '\[#=; backtrack ;=#\]' 'http://www.BillHowell.ca/' >> same problem of leading [space, tab]s : see "$d_SysMaint"'Linux/echo notes.txt' +-----+ https://stackoverflow.com/questions/5127954/echo-changes-my-tabs-to-spaces Echo changes my tabs to spaces Asked 11 years, 11 months ago Modified 10 years, 8 months ago Viewed 15k times Try: cat inputfile.txt | while read line; do echo "$line"; done instead. In other words, it's not read replacing the tabs, it's echo. See the following transcript (using <> where the tabs are): pax$ echo 'hello<>there' | while read line ; do echo $line ; done hello there pax$ echo 'hello<>there' | while read line ; do echo "$line" ; done hello<>there answered Feb 26, 2011 at 16:05 paxdiablo Replacing the tabs is a conspiracy between (ba)sh and echo. echo $line splits line up into words, which are then globbed and passed separately to echo, which then joins them with spaces. echo "$line" passes the string as-is. By comparison, DOS/Windows echo %line% does neither of these things (and indeed even echos quote characters literally). – Neil Feb 26, 2011 at 17:03 13 BTW read will strip leading and trailing whitespace, so if you want to preserve leading/trailing tabs, use ... while IFS= read line ... (note that since the assignment to IFS is a prefix on the read command, it only applies to that and does not have to be reset afterward). – Gordon Davisson Feb 26, 2011 at 17:23 >> Howell: in my case, example : while IFS= read line ; do echo "$line" ; done | sed "s|$strOld448|$strNew448|g" >>"$ptmp448" From : https://stackoverflow.com/questions/5127954/echo-changes-my-tabs-to-spaces Echo changes my tabs to spaces Asked 11 years, 11 months ago answered Feb 26, 2011 at 16:05 paxdiablo changeTo : echo "$line" | while IFS= read line ; do echo "$line" ; done | sed "s|$strOld448|$strNew448|g" >>"$ptmp448" >> didn't work, leading [space, tab]s are lost Oops! changeto : while IFS= read line ; do echo "$line" ; done | sed "s|$strOld448|$strNew448|g" >>"$ptmp448" >> didn't work, went into a loop... CLI example $ echo ' hello there home' | while read line ; do echo "$line" ; done hello there home >> works here, EXCEPT leading tab removed, which is the problem I have +-----+ https://stackoverflow.com/questions/525872/echo-tab-characters-in-bash-script Echo tab characters in bash script Asked 14 years ago Modified 9 months ago Viewed 612k times echo -e ' \t ' will echo 'space tab space newline' (-e means 'enable interpretation of backslash escapes'): $ echo -e ' \t ' | hexdump -C 00000000 20 09 20 0a | . .| edited Feb 16, 2016 at 7:22 Chris Maes answered Feb 8, 2009 at 15:08 Johannes Weiss >>Howell: still strips leading [space, tab]s +--+ Use printf, not echo. There are multiple different versions of the echo command. There's /bin/echo (which may or may not be the GNU Coreutils version, depending on the system), and the echo command is built into most shells. Different versions have different ways (or no way) to specify or disable escapes for control characters. printf, on the other hand, has much less variation. It can exist as a command, typically /bin/printf, and it's built into some shells (bash and zsh have it, tcsh and ksh don't), but the various versions are much more similar to each other than the different versions of echo are. And you don't have to remember command-line options (with a few exceptions; GNU Coreutils printf accepts --version and --help, and the built-in bash printf accepts -v var to store the output in a variable). For your example: res=' 'x # res = "\t\tx" printf '%s\n' "[$res]" And now it's time for me to admit that echo will work just as well for the example you're asking about; you just need to put double quotes around the argument: echo "[$res]" as kmkaplan wrote (two and a half years ago, I just noticed!). The problem with your original commands: res=' 'x # res = "\t\tx" echo '['$res']' # expect [\t\tx] isn't with echo; it's that the shell replaced the tab with a space before echo ever saw it. echo is fine for simple output, like echo hello world, but you should use printf whenever you want to do something more complex. You can get echo to work, but the resulting code is likely to fail when you run it with a different echo implementation or a different shell. answered Nov 17, 2011 at 1:59 Keith Thompson # enddoc