The argument number variable does not count the inputed parameters [duplicate]
This question already has an answer here:
Read Command : How to verify user has typed something
3 answers
What does $# mean in shell?
3 answers
I have the following script :
echo 'Please select type file , the name of the input file and the name of the output file:
a.plain ( please press a ) <input_file> <output_file>;
b.complex ( please press b ) <input_file> <output_file>;'
read one two three
echo $#
if [ $# -ne 3 ]; then
echo "Insufficient arguments !"
exit 1;
else
echo "Number of passed parameters is ok"
fi
$#
always outputs 0 , the read command provides the correct variables when I am using $one , $two and $three later in the script
Thank you.
bash shell-script
marked as duplicate by RalfFriedl, Fabby, G-Man, maxschlepzig, Isaac Nov 24 '18 at 22:44
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
Read Command : How to verify user has typed something
3 answers
What does $# mean in shell?
3 answers
I have the following script :
echo 'Please select type file , the name of the input file and the name of the output file:
a.plain ( please press a ) <input_file> <output_file>;
b.complex ( please press b ) <input_file> <output_file>;'
read one two three
echo $#
if [ $# -ne 3 ]; then
echo "Insufficient arguments !"
exit 1;
else
echo "Number of passed parameters is ok"
fi
$#
always outputs 0 , the read command provides the correct variables when I am using $one , $two and $three later in the script
Thank you.
bash shell-script
marked as duplicate by RalfFriedl, Fabby, G-Man, maxschlepzig, Isaac Nov 24 '18 at 22:44
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
A shell script must start with a#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)
– kasperd
Nov 23 '18 at 23:18
add a comment |
This question already has an answer here:
Read Command : How to verify user has typed something
3 answers
What does $# mean in shell?
3 answers
I have the following script :
echo 'Please select type file , the name of the input file and the name of the output file:
a.plain ( please press a ) <input_file> <output_file>;
b.complex ( please press b ) <input_file> <output_file>;'
read one two three
echo $#
if [ $# -ne 3 ]; then
echo "Insufficient arguments !"
exit 1;
else
echo "Number of passed parameters is ok"
fi
$#
always outputs 0 , the read command provides the correct variables when I am using $one , $two and $three later in the script
Thank you.
bash shell-script
This question already has an answer here:
Read Command : How to verify user has typed something
3 answers
What does $# mean in shell?
3 answers
I have the following script :
echo 'Please select type file , the name of the input file and the name of the output file:
a.plain ( please press a ) <input_file> <output_file>;
b.complex ( please press b ) <input_file> <output_file>;'
read one two three
echo $#
if [ $# -ne 3 ]; then
echo "Insufficient arguments !"
exit 1;
else
echo "Number of passed parameters is ok"
fi
$#
always outputs 0 , the read command provides the correct variables when I am using $one , $two and $three later in the script
Thank you.
This question already has an answer here:
Read Command : How to verify user has typed something
3 answers
What does $# mean in shell?
3 answers
bash shell-script
bash shell-script
edited Nov 23 '18 at 7:53
ctrl-alt-delor
12.2k42561
12.2k42561
asked Nov 23 '18 at 7:48
bboybboy
274
274
marked as duplicate by RalfFriedl, Fabby, G-Man, maxschlepzig, Isaac Nov 24 '18 at 22:44
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by RalfFriedl, Fabby, G-Man, maxschlepzig, Isaac Nov 24 '18 at 22:44
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
A shell script must start with a#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)
– kasperd
Nov 23 '18 at 23:18
add a comment |
A shell script must start with a#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)
– kasperd
Nov 23 '18 at 23:18
A shell script must start with a
#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)– kasperd
Nov 23 '18 at 23:18
A shell script must start with a
#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)– kasperd
Nov 23 '18 at 23:18
add a comment |
3 Answers
3
active
oldest
votes
To test whether you got values for all variables and exit otherwise, use the -z
test to test for empty strings:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
The $#
value is the number of positional parameters, usually command line arguments (or values set by the set
builtin). These are available in $1
, $2
, $3
, etc. (or collectively in the array "$@"
) and are unrelated to the values read by the read
builtin.
To make your script take the input as command line arguments instead of reading them interactively (which may be preferred if the user is to supply one or several paths as they may take advantage of tab-completion, and it also makes it easier to use the script from within another script and does not require that there is a terminal connected), use
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
The script would in this case be run as
./script.sh a.plain /path/to/inputfile /path/to/outputfile
If the processing of the input can happen from standard input and if the output can be sent to standard output (i.e. if you don't actually need the explicit paths of the input file and output file inside the script), then the script only has to take the first parameter (a.plain
or b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
The script would then use the standard input and standard output streams for input and output (and consequently only has to check for a single command line argument).
This would make it possible to run the script with data piped in from another program, and it would also allow for further post-processing:
gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
add a comment |
What you are doing wrong
You are confusing input arguments (to the script, at startup), and user input, using read (at run time).
$#
reports number of arguments at startup. e.g. for ./«script_name» 1 2 3
, when used in the script, it will return 3.
add a comment |
You can use the set
command to re-set the positional arguments, overwriting the previous values. The IFS
variable specifies the list of characters to be used as a separator, so you can also use that to parse CSV. Note that set
is a builtin, so the usual syntax to override variables for single commands does not work, as variables specified before a command are a shorthand for the env
command, which would set the environment for a subprocess.
$#
is the number of positional arguments that currently exist.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
To test whether you got values for all variables and exit otherwise, use the -z
test to test for empty strings:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
The $#
value is the number of positional parameters, usually command line arguments (or values set by the set
builtin). These are available in $1
, $2
, $3
, etc. (or collectively in the array "$@"
) and are unrelated to the values read by the read
builtin.
To make your script take the input as command line arguments instead of reading them interactively (which may be preferred if the user is to supply one or several paths as they may take advantage of tab-completion, and it also makes it easier to use the script from within another script and does not require that there is a terminal connected), use
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
The script would in this case be run as
./script.sh a.plain /path/to/inputfile /path/to/outputfile
If the processing of the input can happen from standard input and if the output can be sent to standard output (i.e. if you don't actually need the explicit paths of the input file and output file inside the script), then the script only has to take the first parameter (a.plain
or b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
The script would then use the standard input and standard output streams for input and output (and consequently only has to check for a single command line argument).
This would make it possible to run the script with data piped in from another program, and it would also allow for further post-processing:
gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
add a comment |
To test whether you got values for all variables and exit otherwise, use the -z
test to test for empty strings:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
The $#
value is the number of positional parameters, usually command line arguments (or values set by the set
builtin). These are available in $1
, $2
, $3
, etc. (or collectively in the array "$@"
) and are unrelated to the values read by the read
builtin.
To make your script take the input as command line arguments instead of reading them interactively (which may be preferred if the user is to supply one or several paths as they may take advantage of tab-completion, and it also makes it easier to use the script from within another script and does not require that there is a terminal connected), use
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
The script would in this case be run as
./script.sh a.plain /path/to/inputfile /path/to/outputfile
If the processing of the input can happen from standard input and if the output can be sent to standard output (i.e. if you don't actually need the explicit paths of the input file and output file inside the script), then the script only has to take the first parameter (a.plain
or b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
The script would then use the standard input and standard output streams for input and output (and consequently only has to check for a single command line argument).
This would make it possible to run the script with data piped in from another program, and it would also allow for further post-processing:
gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
add a comment |
To test whether you got values for all variables and exit otherwise, use the -z
test to test for empty strings:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
The $#
value is the number of positional parameters, usually command line arguments (or values set by the set
builtin). These are available in $1
, $2
, $3
, etc. (or collectively in the array "$@"
) and are unrelated to the values read by the read
builtin.
To make your script take the input as command line arguments instead of reading them interactively (which may be preferred if the user is to supply one or several paths as they may take advantage of tab-completion, and it also makes it easier to use the script from within another script and does not require that there is a terminal connected), use
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
The script would in this case be run as
./script.sh a.plain /path/to/inputfile /path/to/outputfile
If the processing of the input can happen from standard input and if the output can be sent to standard output (i.e. if you don't actually need the explicit paths of the input file and output file inside the script), then the script only has to take the first parameter (a.plain
or b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
The script would then use the standard input and standard output streams for input and output (and consequently only has to check for a single command line argument).
This would make it possible to run the script with data piped in from another program, and it would also allow for further post-processing:
gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
To test whether you got values for all variables and exit otherwise, use the -z
test to test for empty strings:
if [ -z "$one" ] || [ -z "$two" ] || [ -z "$three" ]; then
echo 'Did not get three values' >&2
exit 1
fi
The $#
value is the number of positional parameters, usually command line arguments (or values set by the set
builtin). These are available in $1
, $2
, $3
, etc. (or collectively in the array "$@"
) and are unrelated to the values read by the read
builtin.
To make your script take the input as command line arguments instead of reading them interactively (which may be preferred if the user is to supply one or several paths as they may take advantage of tab-completion, and it also makes it easier to use the script from within another script and does not require that there is a terminal connected), use
if [ "$#" -ne 3 ]; then
echo 'Did not get three command line arguments' >&2
exit 1
fi
one=$1
two=$2
three=$3
The script would in this case be run as
./script.sh a.plain /path/to/inputfile /path/to/outputfile
If the processing of the input can happen from standard input and if the output can be sent to standard output (i.e. if you don't actually need the explicit paths of the input file and output file inside the script), then the script only has to take the first parameter (a.plain
or b.complex
).
./script.sh a.plain </path/to/inputfile >/path/to/outputfile
The script would then use the standard input and standard output streams for input and output (and consequently only has to check for a single command line argument).
This would make it possible to run the script with data piped in from another program, and it would also allow for further post-processing:
gzip -dc <file-in.gz | ./script.sh a.plain | sort | gzip -c >file-out.gz
edited Nov 23 '18 at 8:57
answered Nov 23 '18 at 8:13
Kusalananda♦Kusalananda
138k17258428
138k17258428
add a comment |
add a comment |
What you are doing wrong
You are confusing input arguments (to the script, at startup), and user input, using read (at run time).
$#
reports number of arguments at startup. e.g. for ./«script_name» 1 2 3
, when used in the script, it will return 3.
add a comment |
What you are doing wrong
You are confusing input arguments (to the script, at startup), and user input, using read (at run time).
$#
reports number of arguments at startup. e.g. for ./«script_name» 1 2 3
, when used in the script, it will return 3.
add a comment |
What you are doing wrong
You are confusing input arguments (to the script, at startup), and user input, using read (at run time).
$#
reports number of arguments at startup. e.g. for ./«script_name» 1 2 3
, when used in the script, it will return 3.
What you are doing wrong
You are confusing input arguments (to the script, at startup), and user input, using read (at run time).
$#
reports number of arguments at startup. e.g. for ./«script_name» 1 2 3
, when used in the script, it will return 3.
answered Nov 23 '18 at 7:59
ctrl-alt-delorctrl-alt-delor
12.2k42561
12.2k42561
add a comment |
add a comment |
You can use the set
command to re-set the positional arguments, overwriting the previous values. The IFS
variable specifies the list of characters to be used as a separator, so you can also use that to parse CSV. Note that set
is a builtin, so the usual syntax to override variables for single commands does not work, as variables specified before a command are a shorthand for the env
command, which would set the environment for a subprocess.
$#
is the number of positional arguments that currently exist.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1
add a comment |
You can use the set
command to re-set the positional arguments, overwriting the previous values. The IFS
variable specifies the list of characters to be used as a separator, so you can also use that to parse CSV. Note that set
is a builtin, so the usual syntax to override variables for single commands does not work, as variables specified before a command are a shorthand for the env
command, which would set the environment for a subprocess.
$#
is the number of positional arguments that currently exist.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1
add a comment |
You can use the set
command to re-set the positional arguments, overwriting the previous values. The IFS
variable specifies the list of characters to be used as a separator, so you can also use that to parse CSV. Note that set
is a builtin, so the usual syntax to override variables for single commands does not work, as variables specified before a command are a shorthand for the env
command, which would set the environment for a subprocess.
$#
is the number of positional arguments that currently exist.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1
You can use the set
command to re-set the positional arguments, overwriting the previous values. The IFS
variable specifies the list of characters to be used as a separator, so you can also use that to parse CSV. Note that set
is a builtin, so the usual syntax to override variables for single commands does not work, as variables specified before a command are a shorthand for the env
command, which would set the environment for a subprocess.
$#
is the number of positional arguments that currently exist.
$ read foo
a b c d e
$ echo $foo
a b c d e
$ set -- $foo
$ echo $#
5
$ IFS=: set -- $foo # doesn't work
$ echo $#
5 # still got 5
$ IFS=:
$ set -- $foo
$ echo $#
1
answered Nov 23 '18 at 15:08
Simon RichterSimon Richter
2,5091213
2,5091213
add a comment |
add a comment |
A shell script must start with a
#!
line. If it's missing the kernel will refuse to execute the script. (There are shells which detect this error and attempt to work around it, but they aren't consistent about which interpreter to use. So you'll end up with very inconsistent behavior.)– kasperd
Nov 23 '18 at 23:18