0

I'm trying to learn more bash by updating my bash_profile so that I can quickly do some adb commands that I usually have to copy-paste. I found I was creating many similar functions that all looked like this:

function andVid() {
  minInputs=0
  fileName="$(filNamInc $MEDIA_DIR/Videos/aaaAndroidVideo mp4)"
  origCmd="adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4 $fileName"
  cmd="$(andAddSer $minInputs "$origCmd" "$@")"
  echo "Use ctrl+c to stop recording"
  eval $cmd
}

Usually, when I see a bunch of similar functions, I try to combine them into 1 function. So I made a function that would accept an array of arguments and would do the same actions just dependent on the array:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

function adbRnr() {
  minInputs=$1
  cmd=$2
  if (( $# > 3 )); then
    fileTarget=$3
    fileExtension=$4
    fileName="$(filNamInc $MEDIA_DIR$fileTarget $fileExtension)"
    cmd="$cmd $fileName"
  fi
  if (( $# > $minInputs )); then
    cmd="${cmd:0:4} -s ${@: -1} ${cmd:4}"
  fi
  eval $cmd

(Note: here you see what andAddSer was doing in the first function.) This means that in order to run the function, you need to use a command line entry like this:

adbRnr "${andVid[@]}"

Which is both slow to type and hard to remember. I'd rather enter just the name of the array, and then do the whole "${[@]}" part once it's in the function, such that the command line input would look like this:

adbRnr andVid

However... passing the array name has proved a significant problem. I've tried pretty much every combination of calling the argument with "!", and it hasn't worked. Example:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

function arrayParser() {
  echo "${andVid[*]}"    # echos as expected
  echo $#                # echos "1" as expected
  param=$1               
  echo $param            # echos "andVid" as expected
  cmd=("${!param[3]}")
  echo $cmd              # expected "mp4", nothing printed
}

arrayParser andVid

I know that you can't just pass arrays to functions in bash, but the array I'm referencing is already part of the profile. How do I reference the array using the argument?

0

Using a name reference variable in the function:

arrayParser () {
    declare -n arr="$1"

    printf 'Array: %s\n' "${arr[*]}"
    printf 'Array element at index 3: %s\n' "${arr[3]}"
}

myarray=( alpha beta gamma "bumbling bee" )
arrayParser myarray

Inside the function, any reference to the name reference variable arr will reference the variable passed to the function as its 1st argument.

Name reference variables were introduced in bash release 4.3.

  • This worked perfectly! I had to update bash on my OSX machine, so I am a bit concerned about issues due to that down the line, but it made all my functions work so ¯_(ツ)_/¯ . Thanks a lot! :D – Travesty Apr 4 at 22:49
0

Something like this:

andVid=(4 'adb shell screenrecord --time-limit 60 /sdcard/screenrecord.mp4; sleep 3; adb pull /sdcard/screenrecord.mp4' '/Videos/aaaAndroidVideo' 'mp4')

param=andVid
cmd="\${$param[3]}"
eval echo "$cmd"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.