Question Detail
Suppose I have a script named dd.sh, and I run it like this
./dd.sh sample$name.mp4
So $1
is the string sample$name.mp4
.
echo '$1' // shows $1
echo "$1" // shows "sample.mp4"; want "sample$name.mp4"
Then how to process $1
that I can detect whether there is a dollar sign in parameter $1
I want to process the string to sample\$name.mp4
or just detect whether there is a dollar sign in parameter $filename
Question Answer
As you know, a dollar sign marks a variable. You have to take it into account when you are typing it.
You can escape the dollar
./dd.sh "sample\$name.mp4"
or just type it with single quotes
./dd.sh 'sample$name.mp4'
To check if there is a dollar sign in a variable, do
[[ $variable == *\$* ]] && echo 'I HAZ A DOLAR!!!' || echo 'MEH'
One option:
# Replace occurrences of $ with \$ to prevent variable substitution:
filename="${filename//$/\\$}"
I just realized my prompt was showing foo
rather than foo$bar$baz
as the name of the current branch. foo$bar$baz
was getting assigned to PS1
and $bar
and $baz
were then expanded. Escaping the dollar signs before including the branch name in PS1
prevents unwanted expansions.
Your issue is not with the echo
but with the assignment to $filename
.
You say
filename="sample$name.mp4"
This will interpolate the string, which means expanding the variable $name
. This will result in $filename
having the value sample.mp4
(since $name
is presumably undefined, which means it expands to an empty string)
Instead, use single quotes in the assignment:
filename='sample$name.mp4'
echo "$filename"
will now result in the expected sample$name.mp4
. Obviously, echo '$filename'
will still just print $filename
because of the single quotes.
If your question is:
Then how to process $1 that I can detect whether there is a dollar
sign in parameter $1
You can try this:
if [[ $1 == *'$'* ]]
then
echo '$ was found'
else
echo '$ was not found'
fi
Output:
$ ./dd.sh 'sample$name.mp4' // prints $ was found
$ ./dd.sh 'samplename.mp4' // prints $ was not found
For example you have .env file with variables and password for postgres DB. As you know password should be urlencoded course % sing in password. So we have a problem here. Because BASH ignore $ and we get always wrong password for encode.
.env file
DB_NAME=sone_db
DB_PASS=A1$Bb%!Y$ # with dollar signs
...
bash script
#!/bin/bash
PSQL_COMMAND="DROP schema public CASCADE;"
PSQL_COMMAND+="CREATE schema public;"
set -o allexport
# set source file and get access to all variables in .env
source /path/.env
ENCODED_PASS=$(python -c "from urllib.parse import quote; print(quote('$DB_PASS'))");
psql postgres://$DB_USER:$ENCODED_PASS@$DB_HOST:5432/$DB_NAME -c "$PSQL_COMMAND"
echo $DB_PASS # returns A1%!Y$
echo '$DB_PASS' # returns $DB_PASS
echo "$DB_PASS" # returns A1%!Y$
# disables variables
set +o allexport
# Wont work because BASH find $ sing in string and think that is variable,
so in first and last echo missed part $Bb%
To resolve this you need in .env file escape string in single quote
...
DB_PASS='A1$Bb%!Y$'
...
Demo:
Evidently, the single quotes '
results in no interpolation of enclosing characters.
cat > test.sh
echo '$1'
echo "$1"
% ./test.sh hello
$1
hello
% ./test.sh hello$world
$1
hello
% ./test.sh hello\$world
$1
hello$world << Looks as expected
% ./test.sh 'hello\$world'
$1
hello\$world
% ./test.sh "hello\$world"
$1
hello$world << Looks as expected