0

I am writing a bash script named safeDel.sh with base functionalities including:

  • file [file1, file2, file3...]
  • -l
  • -t
  • -d
  • -m
  • -k
  • -r arg

For the single letter arguments I am using the built in function getops which works fine. The issue I'm having now is with the 'file' argument. The 'file' argument should take a list of files to be moved to a directory like this:

$ ./safeDel.sh file file1.txt file2.txt file3.txt

The following is a snippet of the start of my program :

#! /bin/bash

files=("$@")
arg="$1"
echo "arguments: $arg $files" 

The echo statement shows the following:

$ arguments : file file

How can I split up the file argument from the files that have to be moved to the directory?

2
  • Shellcheck finds one of the problems with the code snippet (incorrect use of an array variable). Commented Nov 7, 2018 at 19:17
  • With an array, echo "$files" is just like echo "${files[0]}" Commented Nov 7, 2018 at 19:43

3 Answers 3

1

Assuming that the options processed by getopts have been shifted off the command line arguments list, and that a check has been done to ensure that at least two arguments remain, this code should do what is needed:

arg=$1
files=( "${@:2}" )

echo "arguments: $arg ${files[*]}"

files=( "${@:2}" ) puts all the command line arguments after the first into an array called files. See Handling positional parameters [Bash Hackers Wiki] for more information.

${files[*]} expands to the list of files in the files array inside the argument to echo. To safely expand the list in files for looping, or to pass to a command, use "${files[@]}". See Arrays [Bash Hackers Wiki].

Sign up to request clarification or add additional context in comments.

1 Comment

Or, arg=$1; shift; files=("$@")
1

This is a way you can achieve your needs:

#!/bin/bash

declare -a files="$@"
for fileToManage in ${files}; do
  echo "Managing ... $fileToManage"
done

But it works only if there is no space in your file names, in which case you need to do some additional work.

Let me know if you need further help.

4 Comments

Parentheses are necessary of you want to safely loop over the files in files or pass them as arguments to other commands. See Why does my shell script choke on whitespace or other special characters?, particularly the "How do I process a list of file names?" section in the (excellent) accepted answer.
Shellcheck identifies inappropriate use of "$@" in the code.
And no space between the pound-bang and the interpreter.
Note that when files names an array, ${files} is equivalent to ${files[0]} which is probably not what's wanted. Use "${files[@]}" to iterate over the elements of the array sanely. The declare -a files="$@" notation maps all the arguments in "$@" into a single argument. You really need declare -a files=("$@") to get multiple elements in the array. See Bash manual on declare and arrays — and experiment.
-1
function getting_arguments {
    # using windows powershell
    echo @($args).GetType()
    echo @($args).length
    echo "@($args)[0]"
    echo @($args)[0]
    echo "@($args)[1..(@($args).length)]"
    echo @($args)[1..(@($args).length)]

    echo "debug: $(@($args)[0])" @($args)[1..(@($args).length)]
}

OUTPUT

PS C:\monkey> getting_arguments 1 2 3 4 5 6

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
6
@(1 2 3 4 5 6)[0]
1
@(1 2 3 4 5 6)[1..(@(1 2 3 4 5 6).length)]
2       
3       
4       
5       
6       
debug: 1
2       
3       
4       
5       
6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.