In Bash, why `x=100 echo $x` doesn't print anything?
The $x
is expanded before echo
runs, and the result is passed to echo
as an argument. echo
does not use the value of x
in its environment.
In the first example, read
uses the value of IFS
in its environment to split the string it receives via the here string.
echo -e doesn't print anything
This is a tough one ;)
Usually you would use double dashes to tell the command that it should stop interpreting options, but echo will only output those:
$ echo -- -e
-- -e
You can use -e itself to get around the problem:
$ echo -e '\055e'
-e
Also, as others have pointed out, if you don't insist on using the bash builtin echo
, your /bin/echo
binary might be the GNU version of the tool (check the man page) and thus understand the POSIXLY_CORRECT
environment variable:
$ POSIXLY_CORRECT=1 /bin/echo -e
-e
I just assigned a variable, but echo $variable shows something else
In all of the cases above, the variable is correctly set, but not correctly read! The right way is to use double quotes when referencing:
echo "$var"
This gives the expected value in all the examples given. Always quote variable references!
Why?
When a variable is unquoted, it will:
Undergo field splitting where the value is split into multiple words on whitespace (by default):
Before:
/* Foobar is free software */
After:
/*
,Foobar
,is
,free
,software
,*/
Each of these words will undergo pathname expansion, where patterns are expanded into matching files:
Before:
/*
After:
/bin
,/boot
,/dev
,/etc
,/home
, ...Finally, all the arguments are passed to echo, which writes them out separated by single spaces, giving
/bin /boot /dev /etc /home Foobar is free software Desktop/ Downloads/
instead of the variable's value.
When the variable is quoted it will:
- Be substituted for its value.
- There is no step 2.
This is why you should always quote all variable references, unless you specifically require word splitting and pathname expansion. Tools like shellcheck are there to help, and will warn about missing quotes in all the cases above.
bash: print x number of blank lines
As Jerry commented you made a syntax error.
This seems to work :
for i in {1..100}
do
echo "\n"
done
Echo newline in Bash prints literal \n
Use printf
instead:
printf "hello\nworld\n"
printf
behaves more consistently across different environments than echo
.
Bash variable not decrementing in a pipeline
It does decrement if you don't use a pipeline (and avoid a sub shell forking):
x=10
f() {
if ((x)); then
echo $((x--))
f
fi
}
Then call it as:
f
it will print:
10
9
8
7
6
5
4
3
2
1
Since decrement is happening inside the subshell hence current shell doesn't see the decremented value of x
and goes in infinite recursion.
EDIT: You can try this work around:
x=10
f() {
if ((x)); then
x=$(tr 0-9 A-J <<< $x >&2; echo $((--x)))
f
fi
}
f
To get this output:
BA
J
I
H
G
F
E
D
C
B
Why can't I specify an environment variable and echo it in the same command line?
What you see is the expected behaviour. The trouble is that the parent shell evaluates $SOMEVAR
on the command line before it invokes the command with the modified environment. You need to get the evaluation of $SOMEVAR
deferred until after the environment is set.
Your immediate options include:
SOMEVAR=BBB eval echo zzz '$SOMEVAR' zzz
.SOMEVAR=BBB sh -c 'echo zzz $SOMEVAR zzz'
.
Both these use single quotes to prevent the parent shell from evaluating $SOMEVAR
; it is only evaluated after it is set in the environment (temporarily, for the duration of the single command).
Another option is to use the sub-shell notation (as also suggested by Marcus Kuhn in his answer):
(SOMEVAR=BBB; echo zzz $SOMEVAR zzz)
The variable is set only in the sub-shell
echo that outputs to stderr
You could do this, which facilitates reading:
>&2 echo "error"
>&2
copies file descriptor #2 to file descriptor #1. Therefore, after this redirection is performed, both file descriptors will refer to the same file: the one file descriptor #2 was originally referring to. For more information see the Bash Hackers Illustrated Redirection Tutorial.
Related Topics
How to Cut an Existing Variable and Assign to a New Variable in Bash
How to Fix "Go Not Root Owned"
Perl Fails to Set Locale Even Though It Is Installed
Backing Up (And Restoring) a Plone Instance
Determining the Path That a Yum Package Installed To
What's the Difference Between Event-Driven and Asynchronous? Between Epoll and Aio
How to Display Modified Date Time with 'Find' Command
Tcp Handshake with Sock_Raw Socket
How to Export Database Schema in Oracle to a Dump File
Get Filesystem Mount Point in Kernel Module
Linux: Modpost Does Not Build Anything
How to Ignore Line Breaks in Input Using Nasm Assembly
Emulating Slurm on Ubuntu 16.04
The Difference Between Initrd and Initramfs
Is It Safe to Delete the Journal File of Mongodb
Using Iconv to Convert from Utf-16Le to Utf-8
How to Get the Exit Code of Spawned Process in Expect Shell Script