What's "set -- "$progname" "$#"" means in shell script? - linux

I current read this line from our configure.ac build script. I have search on Google for answer but not find it.
I assume it is shell script but what does this means, especially for -- ?
set -- "$progname" "$#"

From help set:
-- Assign any remaining arguments to the positional parameters.
If there are no remaining arguments, the positional parameters
are unset.
The reason for -- is to ensure that even if "$progname" or "$#" contain dashes, they will not be interpreted as command line options.
set changes the positional parameters, which is stored in $#. So in this case, it appends "$progname" to the beginning of the positional parameters received by the script.

The -- is a bash built-in as well as something a lot of unix commands use to denote the end of command options. So if you have something like:
grep -- -v file
the -v won't be interpreted as a grep option, but a parameter (so you can grep for -v).
The $# is the list of all the parameters that are passed into the script (which I assume the set command is a part of).
The -- ensures that whatever options passed in as part of the script won't get interpreted as options for set, but as options for the command denoted by the $progname variable.

Related

What do arguments to the "source" command do?

I've encountered the following command:
source foo -c configs/foo.config
What is -c flag is actually may do here? foo is bash script, foo.config also looks like one.
The source command is a bash-specific alias for the POSIX-standardized command .. The specific usage you're asking about is mentioned by POSIX as an allowable extension:
The KornShell version of dot takes optional arguments that are set to the positional parameters. This is a valid extension that allows a dot script to behave identically to a function.
Thus, when code read from foo is invoked, its $1 will be -c and its $2 will be configs/foo.config.
This is also explicitly documented if you run help source in bash:
source: source filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
Exit Status:
Returns the status of the last command executed in FILENAME; fails if
FILENAME cannot be read.
Note the text above: If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed.

How can I escape arguments passed in bash script command line

I have one variable, which is coming from some where like:
VAR1='hhgfhfghhgf"";2Ddgfsaj!!!$#^$\'&%*%~*)_)(_{}||\\/'
Now i have command like this
./myscript.sh '$VAR1'
I am getting that $VAR1 from some diff process and when I display it look exactly as its above.
Now that command is failing as there is already single quote inside variable. In the process where I use it it is expanded at that point, which causes that error.
I have control over myscript.sh but not above command.
Is there any way I can get variable inside my script?
What you are saying is not possible to failing when passing to your script. Might your script has processing issue (or a command where this argument will passing into it) which cannot expand the variable correctly. You can either use printf with %q modifier to escape all special characters then pass it to your script:
./myscript.sh "$(printf '%q\n' "$VAR1")"
... or do the same within your script before you wanted to pass to some other commands:
VAR2="$(printf '%q\n' "$VAR1")"

how to make a general shell to run all C programs without specifying the name

I know I have to take the path first and then run the code like export :$PATH but how do i feed the name of the program to the script?
I have tried to use the command line arguments and try to execute it but it's a dead end.
You can access the first command line argument in the variable "$1", the second with "$2", etc.
To iterate over all the arguments, use
for arg in "$#"; do
do_something_with "$arg"
done

How to use set to change a shell variable?

I am using GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu).
$set | grep SHELL
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:verbose
Now I want to change the value of the SHELL variable to /bin/dash. So I tried
$set SHELL=/bin/dash
set SHELL=/bin/dash
$set | grep SHELL
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:verbose
_=SHELL=/bin/dash
I also tried several other syntax. But the SHELL variable value just doesn't change. I have two questions:
1.How to use set to change the SHELL variable
2.What is _=SHELL=/bin/dash?
The set built-in command has a number of purposes, such as turning tracing on (set -x) or off (set +x). But it also sets the positional parameters — $1, "$#", etc. And that's what you've done with:
set SHELL=/bin/dash
echo "$1"
You'll get SHELL=/bin/dash as the output from the echo.
To set a variable, you set the variable — without any keywords:
SHELL=/bin/dash
The $_ is the value of the last argument of the previous command. For example:
$ cp oldfile.c newfile.c
$ vim $_
…now editing newfile.c
$
This can be useful, but you can also land yourself in problems because $_ changes when you didn't expect it to.
Note that if you were misguided enough to be using a C shell or C shell derivative, then you would use set variable=value to set variables.
In Windows CMD shell, or the Unix csh shells, the set command sets variables.
However, in Bourne-style shells such as bash and dash, you can set variables without any particular command. Setting an environment variable can be as simple as:
MY_VARIABLE=some_value
The set command means something quite different indeed. It's mostly useful in shell scripts, rather than in interactive shells. You use it in a shell script to set the "positional parameters" (as in first argument, second argument, etc). You can also use it to set the shell options like tracing mode (-x), or fail-on-error (-E).
chsh -s {shell-name} {user-name}
use this if you want to change your default shell to dash

Custom command creation

I have used the command alias filecreate='touch $1' in my script to create a new file in my present working directory with the help of filecreate as custom command. But when I execute the script it's showing error. Also how do I make the command to accept 2 parameters one the filename and other the pathname.
alias filecreate=touch
or its function equivalent:
filecreate(){ touch "$#"; }
will accept an arbitrary number of arguments and pass them to touch.
Positional argument expansions usually don't belong in aliases, as aliases, unlike functions, don't get their own positional argument arrays.
Aliases are simple text expansions.
Your
alias filecreate='touch "$1"'
when run like so:
filecreate SomeFile
would simply expand to
filecreate "$1" SomeFile #$1 comes from the caller
This differs from functions and scripts, which do get their own argument array.

Resources