androidadbksh

Understanding what's happening in this script


I have a script, supposedly running in Android 12 ksh that works... but I can't understand why or how.

script begins with:

#!/system/bin/sh
is_sourced() {
  [ "$_" = "is_sourced" ]
}
prt () {
  if is_sourced
  then
    echo "$1"
  else
    log -p i -t "Emotiq" "$1"
  fi
}
...

Then it proceeds to do a lot of work happily printing using prt "message"

I cannot understand why is_sourced manages to reliably detect if I'm sourcing the script or executing it.

Added printouts show $_ is always, irrespective of where in my code is_sourced is called, either "is_sourced" if script was sourced or "./test.sh" (i.e.: the name with which I called the script) if executed.

Can someone explain this behavior? In theory $_ should be the last parameter of last command issued, but that's obviously not true, at least in this case.

I tested using adb shell but this holds true even if script is executed as part of APP setup.


Solution

  • This is a tricky one, $_ is not updated by android's shell when the shell is not interactive.

    Take this script as an example (based on yours):

    #!/system/bin/sh
    is_sourced() {
      echo "\$_=$_"
    }
    
    
    is_sourced
    echo hi
    echo "\$_=$_"
    is_sourced
    

    If you run it from the shell

    emu64a16k:/tmp $ ./myscript
    $_=./myscript
    hi
    $_=./myscript
    $_=./myscript
    

    instead if you source it

    emu64a16k:/tmp $ . ./myscript
    $_=is_sourced
    hi
    $_=hi
    $_=is_sourced
    

    so you can see why it could be used to determine whether the script is running in the current shell or not.