#!/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 "$@"