Re: [ros-users] [Ros-developers] suggest new ros shebang com…

Top Page
Attachments:
Message as email
+ (text/plain)
+ lispscript (text/plain)
+ rosrun (text/plain)
Delete this message
Reply to this message
Author: User discussions
Date:  
To: User discussions
Subject: Re: [ros-users] [Ros-developers] suggest new ros shebang command
I modified rosrun the way I imagined it (attached to this mail), so you
can try it out.
However it turns out I forgot the parameters a scripter might want to
use for his script.
So one has to allow

rosrun PACKAGE EXECUTABLE [ARGS]
rosrun ABSOLUTE_FILENAME [ARGS]

rosrun can still distinguish between those as absolute filenames need to
have a "/" in them, whereas those are forbidden for package names. At
least as long as the ROS community does not want to allow rosrun
STACK/PACKAGE EXECUTABLE [ARGS] to disambiguate packages (but I believe
ROS PACKAGE names need to be unique anyway, else plenty of tools break).

The attached files work this way, once you install the provided rosrun
in your $PATH (E.g. replace your rosrun at your own risk), and make the
lispscript executable, the following should work (it does for me):

$ ./lispscript 2 3
Test, args:
(/home/kruset/work/ros/sandbox/roslisp_support/sbcl/sbcl/bin/sbcl 2 3)

Additional output may be observable depending on your sbcl (LISP)
version, the last line is the one that counts.

You can see how rosrun passes along the command line arguments given to
the script. Of course, rosrun still does what it did for the PACKAGE
EXECUTABLE syntax. The diff to current rosrun is trivial, as my changes
are all contained in one if block. There are 2 minor TODOs left in the
comments that a better scripter than me might fill in quicker than me.
#!/usr/bin/env rosrun
;; /usr/bin/env rosrun roslisp run-roslisp-script.sh --script

(format t "Test, args: ~a~%" sb-ext:*posix-argv*)


#!/bin/bash
if [ $# -lt 1 ]; then
  echo "Usage: rosrun PACKAGE EXECUTABLE [ARGS]"
  echo "or: rosrun ABSOLUTE_FILENAME [ARGS]"
  echo "  rosrun will locate PACKAGE and try to find"
  echo "  an executable named EXECUTABLE in the PACKAGE tree."
  echo "  If it finds it, it will run it with ARGS."
  echo "  The second usage is only intended for shebang scripts."
  exit 1
fi
# if only one arg given to rosrun, or first arg is a path not a name,
# try running absolute filename check for second shebang line first,
# by checking whether first line is shebang and invokes rosrun
if [ $# -lt 2 ] || [[ $1 =~ [a-zA-Z0-9_-.]*/[a-zA-Z0-9_-./]* ]]; then
  if [ ! -e $1 ]; then
    echo "Cannot find file: " $1
    exit 1
  fi
  if [ ! -f $1 ]; then
    echo "Target is a directory: " $1
    exit 1
  fi
  if [ ! -x $1 ]; then
    echo "File is not executable: " $1
    exit 1
  fi


  numlines=0
  while read line
  do
    if [ $numlines = 0 ]; then
      firstline=$line
    fi;
    if [ $numlines = 1 ]; then
      secondline=$line
    fi;
    if [ $numlines = 2 ]; then 
        break
    fi;
    numlines=$(($numlines+1));
  done < $1


  # matches #! ...rosrun, which includes many invalid usages
  # TODO review and maybe make stricter
  if [[ $firstline =~ ^#![[:space:]]?[/a-zA-Z0-9._\s-]+[[:space:]]?rosrun$ ]]; 
  then
    # second shebang line has 2 arbitrary non-blank comment symbols,
    # that we cut off before invoking exec
    if [[ $secondline =~ ^.. ]]
    then
      command=${secondline:2}
      exec $command $*
    else
      echo "rosrun scripts require a second shebang line"
      exit 1        
    fi
  else
    # let bash handle file
    #TODO handle relative filenames, maybe? (not really necessary for script)
    exec $1
  fi
  exit 0
fi
pkgdir=`${ROS_ROOT}/bin/rospack find $1` || exit 2
# The -perm /mode usage is not available in find on the Mac
#exepathlist=(`find $pkgdir -name $2 -type f -perm /u+x,g+x,o+x`)
exepathlist=(`find -H $pkgdir -name $2 -type f  -perm +111 ! -regex ".*$pkgdir\/build\/.*"`)
if [[ ${#exepathlist[@]} == 0 ]] ; then
    echo "[rosrun] Couldn't find executable named $2 below $pkgdir"
    nonexepathlist=(`find -H $pkgdir -name $2`)
    if [[ ${#nonexepathlist[@]} != 0 ]] ; then
      echo "[rosrun] Found the following, but they're either not files, "
      echo "[rosrun] or not executable:"
      for p in ${nonexepathlist[@]}; do
        echo "[rosrun]   ${p}"
      done
    fi
    exit 3
elif [[ ${#exepathlist[@]} -gt 1 ]] ; then
    echo "[rosrun] You have chosen a non-unique executable, please pick one of the following:"
    select opt in ${exepathlist[@]}; do
        exepath=$opt
        break
    done
else
    exepath=${exepathlist[0]}
fi
shift
shift
exec $exepath "$@"