I'm writing a bash script and when I write the line:
echo "l=l.split('\n')"
I would like the output to actually be l=l.split('\n') but get:
l=l.split('
')
Any idea on how to fix this? I tried using quotations at different spots and escaping the characters differently but nothing seems to be working. Appreciate the help!
**Worth noting - if I simply type the echo command into the terminal I get my desired output.. Not sure why a script is treated differently.
It sounds like perhaps you got the shebang wrong (for a bash script, anyway). Take for example:
$ cat test.sh
#!/bin/sh
echo "l=l.split('\n')"
$ ./test.sh
l=l.split('
')
$ cat test.bash
#!/bin/bash
echo "l=l.split('\n')"
$ ./test.bash
l=l.split('\n')
Even though bash and sh may be provided by the same shell on some systems, there are subtle differences in their behavior. If you want it to behave like it does for you in a terminal, be sure to use #!/bin/bash.
tl;dr
If your script is really being run by bash, then something must have turned on the off-by-default xpg_echo shell option - either directly, or indirectly via shell option posix.
posix is implicitly turned on when Bash is invoked as sh (/bin/sh), which happens on macOS, for instance.
If your script is not being run by bash, which is the likeliest explanation, as suggested in FatalError's helpful answer:
Ensure that your script's shebang line is either
#!/bin/bash or #!/usr/bin/env bash.
Alternatively, pass it directly to bash: bash <script>
The portable solution, which shields you from variable echo behavior, is to use printf as follows:
printf '%s\n' "l=l.split('\n')"
Optional background information
In bash, the interpretation of escape sequences such as \n by echo is turned OFF by default.
Option xpg_echo must be turned on for escape sequences to be recognized by echo.
This option is implicitly on if you run bash in POSIX compatibility mode (verify with shopt -o posix), which also happens if you run Bash as sh, as is the case on macOS, for instance, where /bin/sh is Bash.
Note that irrespective of the state of xpg_echo by itself, you can opt into escape-sequence interpretation ad-hoc with echo -e and opt out with echo -E.
However, this does not work when running in POSIX compatibility mode (shopt -o posix), where - in compliance with POSIX - echo supports no options at all.
In other words: The following would only work if (a) your script is really being executed by bash and (b) option posix is off:
echo -E "l=l.split('\n')"
Again, printf is the portable, POSIX-compliant alternative that works consistently across all POSIX-compatible shells, irrespective of the state of shell options:
# '%s\n': *without* escape-sequence interpretation
$ printf '%s\n' "l=l.split('\n')"
l=l.split('\n')
# '%b\n': *with* escape-sequence interpretation
$ printf '%b\n' "l=l.split('\n')"
l=l.split('
')
This solves the problem.
echo "l=l.split('\\\n')"
Related
This question already has answers here:
echo printing -e in bash
(2 answers)
Closed 3 years ago.
The "-e" option in "echo" means that support escape sequences. However, I found it would output "-e" instead.
I have written a shell script and run it to get an "-e" result. And I have typed the same command on my zsh interactive shell, and I got an ideal result.
#!/bin/sh
echo -e "test"
I expect the output to be test, but the actual output is -e test.
The "-e" option in "echo" means that support escape sequences.
That depends on which echo you're using, the one built into your shell (and if so, which shell) or the /bin/echo executable. It's not portable.
Apparently your /bin/sh doesn't support the -e option in echo .
Standard echo doesn't support any arguments:
OPTIONS
The echo utility shall not recognize the "--" argument in the manner specified by Guideline 10 of XBD Utility Syntax Guidelines; "--" shall be recognized as a string operand.
Implementations shall not support any options.
Then again, backslash-escapes are either undefined, or (in XSI-complient systems) expanded.
The actual implementations differ. Bash's echo doesn't expand backslash-escapes, except with the -e switch. Dash (Debian's and Ubuntu's /bin/sh) expands them, and doesn't know about -e. Zsh also expands them by default, but recognizes (and ignores) the -e, and has -E to disable expanding backslash-escapes.
To be on a safer side, use printf instead.
I bet when you do ls -la /bin/sh it is a symlink to dash.
$> dash -c 'echo -e test'
-e test
$> dash -c '/bin/echo -e test'
test
In python to make a beep I print the control character 07. For example:
>>> print('\x07')
# <beep>
Is it possible to do this from the shell? I've been trying things like:
david$ echo \x07
x07
david$ echo '\x07'
\x07
david$ echo "\x07"
\x07
But just prints it literally. How could this be done, outside of doing something like:
$ python -c "print('\x07')"
Seems like printf works:
$ printf '\a'
Any way to do this with echo as well?
It's actually quite easy:
printf "\a"
prints the alarm/bell character.
The problem with echo is that POSIX says
If the first operand is -n, or if any of the operands contain a character, the results are implementation-defined.
And, indeed, depending on your shell if using a built-in version (And which shell it is), or your OS if using a free standing echo, some will interpret backslash escapes by default, some require a specific option (Usually -e) to do so, some (zsh) depend on what a shell option is set to... it's easier to just use printf, which will always behave the same way with respect to escape sequences like \a.
For Bash, the built-in echo command supports escaping:
echo -ne '\a'
For a POSIX-compliant shell, printf is a better option:
printf '\a'
Or with GNU Core Utilities:
/bin/echo -ne '\a'
This question already has answers here:
echo printing -e in bash
(2 answers)
Closed 3 years ago.
The "-e" option in "echo" means that support escape sequences. However, I found it would output "-e" instead.
I have written a shell script and run it to get an "-e" result. And I have typed the same command on my zsh interactive shell, and I got an ideal result.
#!/bin/sh
echo -e "test"
I expect the output to be test, but the actual output is -e test.
The "-e" option in "echo" means that support escape sequences.
That depends on which echo you're using, the one built into your shell (and if so, which shell) or the /bin/echo executable. It's not portable.
Apparently your /bin/sh doesn't support the -e option in echo .
Standard echo doesn't support any arguments:
OPTIONS
The echo utility shall not recognize the "--" argument in the manner specified by Guideline 10 of XBD Utility Syntax Guidelines; "--" shall be recognized as a string operand.
Implementations shall not support any options.
Then again, backslash-escapes are either undefined, or (in XSI-complient systems) expanded.
The actual implementations differ. Bash's echo doesn't expand backslash-escapes, except with the -e switch. Dash (Debian's and Ubuntu's /bin/sh) expands them, and doesn't know about -e. Zsh also expands them by default, but recognizes (and ignores) the -e, and has -E to disable expanding backslash-escapes.
To be on a safer side, use printf instead.
I bet when you do ls -la /bin/sh it is a symlink to dash.
$> dash -c 'echo -e test'
-e test
$> dash -c '/bin/echo -e test'
test
I found this example:
echo -e "This is red->\e[00;31mRED\e[00m"
It works if execute direct, from command line, bu if create file like:
#! /usr/bin/sh
echo -e "This is red->\e[00;31mRED\e[00m"
Doesn't work. How to fix? Or may be possible output in bold?
Please don't use Lua it doesn't installed.
Edit This might be your problem (likely):
#!/bin/bash
echo -e "This is red->\e[00;31mRED\e[00m"
The reason is that sh doesn't have a builtin echo command, that supports escapes.
Alternatively you might invoke your script like
bash ./myscript.sh
Backgrounders
ANSI escape sequences are interpreted by the terminal.
If you run in a pipe/with IO redirected, ouput won't be to a terminal, hence the escapes don't get interpreted.
Hints:
see ansifilter for a tool that can filter ANSI escape sequences (and optionally translate to HTML and others)
use GNU less, e.g. to get ANSI escapes working in a pager:
grep something --colour=always files.* | less -R
Or simply, as I do
# also prevent wrapping long lines
alias less='less -SR'
Use an echo program, not an echo built-in command:
#!/bin/sh
MYECHO="`which echo`"
if <test-whether-MYECHO-empty-and-act-accordingly> ...
...
$MYCHO -e "This is red->\e[00;31mRED\e[00m"
I've read the man pages on echo, and it tells me that the -e parameter will allow an escaped character, such as an escaped n for newline, to have its special meaning. When I type the command
$ echo -e 'foo\nbar'
into an interactive bash shell, I get the expected output:
foo
bar
But when I use this same command (i've tried this command character for character as a test case) I get the following output:
-e foo
bar
It's as if echo is interpretting the -e as a parameter (because the newline still shows up) yet also it interprets the -e as a string to echo. What's going on here? How can I prevent the -e showing up?
You need to use #!/bin/bash as the first line in your script. If you don't, or if you use #!/bin/sh, the script will be run by the Bourne shell and its echo doesn't recognize the -e option. In general, it is recommended that all new scripts use printf instead of echo if portability is important.
In Ubuntu, sh is provided by a symlink to /bin/dash.
Different implementations of echo behave in annoyingly different ways. Some don't take options (i.e. will simply echo -e as you describe) and automatically interpret escape sequences in their parameters. Some take flags, and don't interpret escapes unless given the -e flag. Some take flags, and interpret different escape sequences depending on whether the -e flag was passed. Some will cause you to tear your hair out if you try to get them to behave in a predictable manner... oh, wait, that's all of them.
What you're probably seeing here is a difference between the version of echo built into bash vs /bin/echo or maybe vs. some other shell's builtin. This bit me when Mac OS X v10.5 shipped with a bash builtin echo that echoed flags, unlike what all my scripts expected...
In any case, there's a solution: use printf instead. It always interprets escape sequences in its first argument (the format string). The problems are that it doesn't automatically add a newline (so you have to remember do that explicitly), and it also interprets % sequences in its first argument (it is, after all, a format string). Generally, you want to put all the formatting stuff in the format string, then put variable strings in the rest of the arguments so you can control how they're interpreted by which % format you use to interpolate them into the output. Some examples:
printf "foo\nbar\n" # this does what you're trying to do in the example
printf "%s\n" "$var" # behaves like 'echo "$var"', except escapes will never be interpreted
printf "%b\n" "$var" # behaves like 'echo "$var"', except escapes will always be interpreted
printf "%b\n" "foo\nbar" # also does your example
Use
alias echo /usr/bin/echo
to force 'echo' invoking coreutils' echo which interpret '-e' parameter.
Try this:
import subprocess
def bash_command(cmd):
subprocess.Popen(['/bin/bash', '-c', cmd])
code="abcde"
// you can use echo options such as -e
bash_command('echo -e "'+code+'"')
Source: http://www.saltycrane.com/blog/2011/04/how-use-bash-shell-python-subprocess-instead-binsh/