Why does * put all file names in the argument vector? [duplicate] - bash

This question already has answers here:
What is file globbing?
(1 answer)
Stop shell wildcard character expansion?
(4 answers)
command line * linux [duplicate]
(1 answer)
Closed 4 years ago.
I stumbled upon this while working through the exercises in K&R2. Why does echo * prints the names of all files in the current directory? More generally, when I write a C program that takes command-line arguments, and when I give it * as an argument, it puts the names of all files in its parent directory in to the argument vector. Why does this happen? What is so special about *?
I could not find anything about this in the internet.

This is called globbing. Here's a detailed description. Other wildcards include ? for one character, [abc] for one of a set of characters, and [a-z] for one of a range of characters. This is built into various shells, including Bash.
In response to your comment "I think echo is written in C" — this doesn't matter a bit. Once source code is compiled into an executable containing machine code, it doesn't matter what language it was written in.

Related

What does the #*$ in a shell script's string interpolation do? [duplicate]

This question already has answers here:
What is the meaning of the ${0##...} syntax with variable, braces and hash character in bash?
(4 answers)
Closed 11 months ago.
I found the following code in a shell script, but I am unsure of what the test condition is evaluating for
if test "${SOME_VAR#*$from asdf/qwer}" != "$SOME_VAR"; then
echo "##zxcv[message text='some text.' status='NORMAL']";
fi
The combination #*$ does not mean anything special. There are three special symbols and each of them has its own meaning in this context.
${SOME_VAR#abc} is a parameter expansion. Its value is the value of $SOME_VAR with the shortest prefix that matches abc removed.
In your example, abc is *${from} asdf/qwer. That means anything * followed by the value of variable $from (which is dynamic and replaced when the expression is evaluated), followed by a space and followed by asdf/qwer.
All in all, if the value of $SOME_VAR starts with a string that ends in ${from} asdf/qwer then everything before and including asdf/qwer is removed and the resulting value is passed as the first argument to test.
Type man bash in your terminal to read the documentation of bash or read it online.

Extract the pointer from a V_${i}_T variable name in a bash loop [duplicate]

This question already has answers here:
Bash - variable variables [duplicate]
(4 answers)
Dynamic variable names in Bash
(19 answers)
Closed 4 years ago.
Suppose I have several variable names like
V_1_T = a
V_2_T = b
V_3_T = c
...
and I want to extract the pointers a, b , c, ... in a bash loop in order to concatenate the values. My explicit wish is about reconstructing a message separated in several parts as explained in the gammu-smsd documentation.
I've tried the example in the doc but it doesn't work. The reason is that the code never points to the pointer of the variables but to the variables themselves, i.e. I get V_1_T at best and never a as I would.
I've also tried to put
${V_${i}_T} ; ""$"V_${i}_T"
with and without escape symbols for the commas, ..., but nothing worked ...
Any ideas ?
I'm working on the latest version of Raspbian + RaspberryPi.
Use indirect parameter expansion:
for i in 1 2 3; do
t="V_${i}_t"
echo "${!t}"
done
This avoids the use of eval shown in the docs you linked to.

How to encase a command line argument in quotes with a bash/shell script [duplicate]

This question already has answers here:
How do I pass in the asterisk character '*' in bash as arguments to my C program?
(5 answers)
The issue of * in Command line argument
(6 answers)
Closed 5 years ago.
How do I write a bash script/function that will take a command line argument with spaces and interpret it as if it had quotes around it.
ie: echo this is some text as if echo "this is some text"
What I want to do is create a simple CLI calculator script/function.
Here is what I have:
calc() {
echo $(($#))
}
On the CLI, all of these work:
"# +-/* ", #+-/*, # +-/ #
ie:
calc 10+2
12
but this one produces an error:
calc 10 * 2
-bash: 10 calc.sh 2: syntax error: invalid arithmetic operator (error token is ".sh 2")
Any ideas? It's not a big deal to include the quotes in the calculations, but if possible it would be quicker/more convenient to not include them. Is there any way to take a string after calc from first character to last and then pass it through quotes in the script?
In unix systems there is a variable called IFS. This variable decides at what signs the console separate the string into words. In theory you could chang the IFS variable, but this is really not advisable (as it will breake other bash commands).
Better: you could write your utillity in such way, that writing 'calc' will prompt the user to type his equation to standard in. Then you can read the text the user types and parse it in any way you want.
Even better: a shell script can specify that it wishes for an arbitrary nimber of words as input. Take all the words the user writes and then parse that. See: How to define a shell script with variable number of arguments?

Double expansion of a parameter in Bash script [duplicate]

This question already has answers here:
Lookup shell variables by name, indirectly [duplicate]
(5 answers)
Closed 7 years ago.
I want to expand a parameter twice, and ${$PARAM} doesn't work.
For example, if I set two variables to file names and then want to loop through those variables and expand to their file names:
INPF_1=input1.inp
INPF_2=input2.inp
# copy the input files to the execution directory
for input_param in ${!INPF_*}; do
echo ${$input_param}
done
How can I to access the file names from those parameters in the for loop?
I.e., expand to input1.inp and input2.inp.
You had it almost: just use "${!input_param}" instead of ${$input_param}.
The quoting doesn't do anything in this case, but it's a good habit.
Be aware of the difference to ${!INPF_#}, which – when used between double quotes – expands to a separate word for each variable name, whereas "${!INPF_*}" doesn't. You almost always want "${!INPF_#}". See the difference:
$ for var in "${!INPF_*}"; do echo "$var"; done
INPF_1 INPF_2
$ for var in "${!INPF_#}"; do echo "$var"; done
INPF_1
INPF_2
See the manual for the various parameter expansions.

why we use ##*/ expression with bash variable [duplicate]

This question already has answers here:
explain the linux regex for getting filename
(2 answers)
Closed 8 years ago.
I am tring to understand the bash script.
I am seeing ##* / expression with bash variable.
i.e ${foo##*/}
Can someone please tell me why we use that expression?
It's called "Parameter expansion". The variable $foo is searched for a substring matching the pattern */ (i.e. anything up to a slash) from the beginning (#), and what remains in the variable is returned. Doubling the #-sign makes the matching greedy, i.e. it tries to find the longest possible match.

Resources