Using curly brace { as an input to tcsh Linux script - linux

This question is regarding tcsh scripting in Linux. Suppose I want the user to enter a username and a password and then let the script check them both. If the user has a curly brace { in his password, the script won't work at all by claiming:
Missing }.
Is there a way to overcome this? Is there a way to start the script anyway so it will handle the curly brace from the inside?
Thanks, Poly

Assuming you're reading input with $<, quote the substitution:
set password = $<:q

Thanks for all the viewers and dave sines for answering.
The answer is:
If you are using $argv it will fail.
If you use "$argv" it will work.
So, if an argument can contain a curly brace { then use double quotes to wrap $argv in order to read it correctly.
Poly

In csh, 2 single quotes can be used to protect (escape) curly braces. You may need one double quote (") when you echo the variable:
set a=''{''
echo "$a"
If you use curly braces (or brackets, [ ]) in a script, you can combine echo within back-quotes () and the escaped brackets:
set b = " COMMANDS `echo ''{''` MORE COMMANDS `echo ''}''` "
echo "$b"

Related

linux bash, passing paramenters using a varible issue

I am trying to use a variable to store the parameters, here is the simple test:
#!/bin/bash
sed_args="-e \"s/aaaa/bbbb/g\""
echo $sed_args`
I expected the output to be
-e "s/aaaa/bbbb/g"
but it gives:
"s/aaaa/bbbb/g"
without the "-e"
I am new to bash, any comment is welcome. Thanks, maybe this is already answered somewhere.
You need an array to construct arguments dynamically:
#!/usr/bin/env bash
sed_args=('-e' 's/aaaa/bbbb/g')
echo "${sed_args[#]}"
When you use the variable without double quotes, it gets word split by the shell even before echo sees the value(s). Then, the bash's builtin echo interprets -e as a parameter for itself (which is normally used to turn on interpretation of backslash escapes).
When you double quote the variable, it won't be split and will be interpreted as a single argument to echo:
echo "$sed_args"
For strings you don't control, it's safer to use printf as it doesn't take any arguments after the format string:
printf %s "$string"

bash echo environment variable containing escaped characters

I have an script that echo the input given, into a file as follows:
echo $# > file.txt
When I pass a sting like "\"" I want it to exactly print "\"" to the file however it prints ".
My question is how can I print all characters of a variable containing a string without considering escapes?
When I use echo in bash like echo "\"" it only prints " while when I use echo '"\""' it prints it correctly. I thought maybe that would be the solution to use single quotes around the variable, however I cannot get the value of a variable inside single quotes.
First, note that
echo $# > file.txt
can fail in several ways. Shellcheck identifies one problem (missing quotes on $#). See the accepted, and excellent, answer to Why is printf better than echo? for others.
Second, as others have pointed out, there is no practical way for a Bash program to know exactly how parameters were specified on the command line. For instance, for all of these invocations
prog \"
prog "\""
prog '"'
the code in prog will see a $1 value that consists of one double-quote character. Any quoting characters that are used in the invocation of prog are removed by the quote removal part of the shell expansions done by the parent shell process.
Normally that doesn't matter. If variables or parameters contain values that would need to be quoted when entered as literals (e.g. "\"") they can be used safely, including passing them as parameters to other programs, by quoting uses of the variable or parameter (e.g. "$1", "$#", "$x").
There is a problem with variables or parameters that require quoting when entered literally if you need to write them in a way that they can be reused as shell input (e.g. by using eval or source/.). Bash supports the %q format specification to the printf builtin to handle this situation. It's not clear what the OP is trying to do, but one possible solution to the question is:
if (( $# > 0 )) ; then
printf -v quoted_params '%q ' "$#" # Add all parameters to 'quoted_params'
printf '%s\n' "${quoted_params% }" # Remove trailing space when printing
fi >file.txt
That creates an empty 'file.txt' when no positional parameters are provided. The code would need to be changed if that is not what is required.
If you run echo \", the function of the backslash in bash is to escape the character after it. This actually enables you to use the double quotes as an argument. You cannot use a backslash by itself; if you want to have a backslash as an argument you need to use another slash to escape that: echo \\
Now if you want to create a string where these things are not escaped, use single quotes: echo '\'
See for a better explanation this post: Difference between single and double quotes in Bash

Escape braces in ksh

I am trying to prepare JSON in ksh file. I am facing this problem - I think it's because I can't properly use braces. Example:
RESULT="[";
COUNTRY=mCountry
LANGUAGE=mLang
AppendParams()
{
RESULT=$RESULT"{\"site:\"$COUNTRY\",\"lang\":\"$LANGUAGE\"}";
}
AppendParams
RESULT=$RESULT"]";
echo $RESULT;
Output is:
sh-4.3$ ksh main.ksh
["site:"mCountry"] ["lang":"mLang"]
Instead of
[{"site:"mCountry","lang":"mLang"}]
Is there a way to disable braces or escape them? Please help.
When you echo or print a variable whose value might contain a brace, double-quote the variable name like "${VARIABLE}" to avoid brace expansion. Also you might use single quotes to avoid having to escape every double-quote. Try:
AppendParams()
{
RESULT=${RESULT}'{"site:"'${COUNTRY}'","lang":'${LANGUAGE}'"}'
}
AppendParams
RESULT=$RESULT"]"
echo "$RESULT"

BASH: A variable inside a defined variable?

i have the following function in a bash script which does not work?
do_get() {
cmd='<command version="33" cmd="GETINFO" $3</command>'
echo $cmd
}
Now, if i echo $3 right before the cmd variable it echos out 1234 which i am passing as a 3 argument when executing this. BUT it shows just $3 when i do an echo $cmd.
i tried a couple of things like such below thinking its getting striped out
'$3' but it then shows blank
'"$3"' same as above
The variable doesn't expand when inside single quotes. You need to use double quotes instead, but since you have double quotes on the inside, you need to make sure you remember to escape those as well.
do_get() {
cmd="<command version=\"33\" cmd=\"GETINFO\" $3</command>"
echo $cmd
}
Newer versions of bash add a -v flag to the printf command that makes assignments like this a little easier on the eye, in that quoting is reduced.
printf -v cmd '<command version="33" cmd="GETINFO" %d </command' "$3"
The single quote in Bash prevents variable substitution. In order for the third parameter to be substituted, you should enclose your string in double quotes. of course, you have the problem of the double quotes that are part of your string, so they need to be escaped with a backslash:
cmd="<command version=\"33\" cmd=\"GETINFO\" $3 </command>"

How to echo "$x_$y" in Bash script?

It is very interesting that if you intend to display 0_1 with Bash using the code
x=0
y=1
echo "$x_$y"
then it will only display
1
I tried echo "$x\_$y" and it doesn't work.
How can I echo the form $x_$y? I'm going to use it on a file name string.
Because variable names are allowed to have underscores in them, the command:
echo "$x_$y"
is trying to echo ${x_} (which is probably empty in your case) followed by ${y}. The reason for this is because parameter expansion is a greedy operation - it will take as many legal characters as possible after the $ to form a variable name.
The relevant part of the bash manpage states:
The $ character introduces parameter expansion, command substitution, or arithmetic expansion.
The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name.
When braces are used, the matching ending brace is the first } not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or parameter expansion.
Hence, the solution is to ensure that the _ is not treated as part of the first variable, which can be done with:
echo "${x}_${y}"
I tend to do all my bash variables like this, even standalone ones like:
echo "${x}"
since it's more explicit, and I've been bitten so many times in the past :-)
This way:
$ echo "${x}_${y}"
0_1
wrap it in curly braces:
echo "${x}_${y}"
Just to buck the trend, you can also do this:
echo $x'_'$y
You can have quoted and unquoted parts next to each other with no space between. And since ' isn't a legal character for a variable name, bash will substitute only $x. :)

Resources