exists.sh 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/bin/sh
  2. # Posix shell function for finding executable files in the $PATH
  3. # Copyright 2016-2022 orbea
  4. # All rights reserved.
  5. #
  6. # Redistribution and use of this script, with or without modification, is
  7. # permitted provided that the following conditions are met:
  8. #
  9. # 1. Redistributions of this script must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. #
  12. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
  13. # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  15. # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  16. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  17. # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  18. # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  19. # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  20. # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  21. # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. set -euf
  23. exists () {
  24. ALLMATCHES=
  25. while [ $# -gt 0 ]; do
  26. case "$1" in
  27. -- ) shift; break ;;
  28. -a|--all ) ALLMATCHES=1; shift ;;
  29. -h|--help ) printf %s\\n "usage: $0 [-a] command [arg ...]"; exit 0 ;;
  30. -* ) printf %s\\n "$0: Illegal option $1" >&2; exit 1 ;;
  31. * ) break ;;
  32. esac
  33. done
  34. r=0; cwd="$(pwd)"
  35. while [ $# -gt 0 ]; do
  36. v=1; arg="$1"; shift
  37. case "$arg" in
  38. ''|*/ )
  39. :
  40. ;;
  41. /* )
  42. if [ -f "$arg" ] && [ -x "$arg" ]; then
  43. printf %s\\n "$arg"
  44. v=0
  45. fi
  46. ;;
  47. ./* )
  48. if [ -f "$arg" ] && [ -x "$arg" ]; then
  49. pre="$(cd -- "${arg%%/*}/" && pwd)"
  50. printf %s\\n "${pre%/}/$arg"
  51. v=0
  52. fi
  53. ;;
  54. */* )
  55. if [ -f "$arg" ] && [ -x "$arg" ]; then
  56. printf %s\\n "$(cd -- "${arg%%/*}/.." && pwd)/$arg"
  57. v=0
  58. fi
  59. ;;
  60. * )
  61. if [ -n "${PATH+x}" ]; then
  62. p=":${PATH:-$cwd}"
  63. while [ "$p" != "${p#*:}" ] && [ -n "${p#*:}" ]; do
  64. p="${p#*:}"; x="${p%%:*}"; z="${x:-$cwd}"; d="${z%/}/$arg"
  65. if [ -f "$d" ] && [ -x "$d" ]; then
  66. case "$d" in
  67. /* ) : ;;
  68. ./* ) pre="$(cd -- "${d%/*}/" && pwd)"; d="${pre%/}/$d" ;;
  69. * ) d="$(cd -- "${d%/*}/" && pwd)/$arg" ;;
  70. esac
  71. printf %s\\n "$d"
  72. v=0
  73. [ -n "${ALLMATCHES}" ] || break
  74. fi
  75. done
  76. fi
  77. ;;
  78. esac
  79. [ $v = 0 ] || r=1
  80. done
  81. return $r
  82. }
  83. if [ -n "${1+x}" ]; then
  84. exists "${@:-}"
  85. else
  86. exists
  87. fi