0

I have a script that i give it arguments. The first argument is a string and the others are numbers.I want to check if the arguments from the second and then is numbers(except the string).

k="$1"

shift

declare -i x

x=($*)
for i in ${x[@]}
do
        if [ $i == 0 ]
        then
                echo "give dec or incr and numbers only"
                exit 1
        fi
        
done

but it does not work. It takes all the arguments.Declare -i x means that x takes only numbers and if not returns 0.I want the x array take from the second argument onwards

  • Actually, since you have used `shift`, `x` contains all but the first (original) arguments. If you want to skip the first of the remaining ones, use a couting loop over the array `x`, starting with index 1 (since in bash, index 0 refers to the first argument in an array). – user1934428 Dec 14 '22 at 11:40
  • The `declare -i x` does not make sense, since `x` is an **array**. `-i` tells bash to treat `x` as an integer **scalar**. I don't know whether this is harmful or just redundant; I could imagine that the declaration is simply wiped out by the following array assignment. Still, I would remove it. – user1934428 Dec 14 '22 at 11:46
  • `x=( $* )` is inherently buggy. It's `x=( "$@" )` to copy the whole argv into an array. – Charles Duffy Dec 14 '22 at 22:56

1 Answers1

-2

This modification of your script

  • captures the remaining command line items into the array;
  • reports the array size; and
  • reports the value assigned to the individual array elements

The script is as follows:

#!/bin/bash

k="$1"
shift
declare -i x

# Assigning values from command line
x=( "$@" )     ### edited assignment command
echo "Assigned array items:  ${x[@]}"

size=${#x[*]}
echo "Array size = ${size}"

i=0
max=$((${size}-1))
while [ $i -le ${max} ]
do
    echo "x[$i] = ${x[$(expr $i )]}"
    ((i+=1))
done

Note that there is no necessity to use declare in scripts where input data is of known type (i.e. position 2-6 of your inputs. Most programs work with data in a predefined known format. Even without using typing, those would normally check for "empty value" conditions.

"declare" would only be used where

  • input types are of unknown type, AND
  • the consequences of an invalid type would have severe impact in terms of the usage of the invalid data to contain the path for actions (i.e. rm -rf ${variable}) or would lead to manipulation/corruption of the incorrect partition (i.e. ${partition} == 0 during a semi-automated process to modify/repair with fsck or parted.
Eric Marceau
  • 1,601
  • 1
  • 8
  • 11
  • 1
    `x=( $(echo $*) )` is adding two completely unnecessary indirection areas, and a bunch of bugs in the process. If someone runs `./yourprogram 'hello world *.txt' 'second argument'`, you don't want that changed into `'hello' 'world' a.txt b.txt c.txt 'second' 'argument'`, but that's effectively what this code does (if run in a directory with three text files named `a.txt`, `b.txt` and `c.txt`). – Charles Duffy Dec 14 '22 at 22:58
  • 1
    See [I just assigned a variable but `echo $variable` shows something else](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) – Charles Duffy Dec 14 '22 at 22:59
  • 1
    Also, [What is the difference between `$*` and `$@`?](https://stackoverflow.com/questions/22589032/what-is-the-difference-between-and) – Charles Duffy Dec 14 '22 at 22:59
  • 1
    ...which is all to say, it _really_ should be `x=( "$@" )` after the `shift`, with no `$*` anywhere, with one exception for your `echo`: if targeting bash 5.x, consider `echo "Assigned array items: ${*@Q}"` to print contents escaped in an unambiguous form. – Charles Duffy Dec 14 '22 at 23:01
  • When I code for responses, I don't code for perfect terseness. I code for demonstration of clear, distinct forms that work for various tasks, broken piecemeal. Yes, some of that is not "necessary", but that is the way I approach it. – Eric Marceau Dec 14 '22 at 23:28
  • 1
    The concern is correctness, not terseness. Doing unnecessary string splitting and globbing can result in incorrect/unwanted output; in one of my former employers that error was the root cause of a major data loss incident. – Charles Duffy Dec 16 '22 at 11:27
  • I understand hard-won knowledge. I have never experienced what you have described, during my 30 years of HP-UX/Solaris/Linux. I updated the code per your comments. – Eric Marceau Dec 16 '22 at 20:37