-2

For a shell script I need to call an executable by name, regardless of the path leading there; thus far I know this code reports the right name:

tmpprog=`which program`
prog=${tmpprog%%*/}
if $prog=""
then
  echo >&2 "Main Program not found"
else
  echo >&2 "$prog"
fi

How can I cut the code so that I may trim the path to keep the executable name and remove the path in a one liner?

Beware: basename won't do it, since I may be working on a hybrid environment (cygwin/busybox on windoze), and sometimes the paths have spaces.

peterh
  • 9,731
jarnosc
  • 200
  • 3
    Just run program directly? Why go to this effort of finding where program is located to then discard that information? – muru Jan 16 '24 at 03:47
  • I'm running a test so that, if finding the program fails, I may fallback to a substitute procedure; and as I said, I cannot rely on the consistency of how to handle paths in a hybrid environment. – jarnosc Jan 16 '24 at 05:53
  • 1
    Ok, but that still doesn't explain why you need to do anything with the path at all. Fallback to substitute procedure or do whatever if the test fails, but if the test succeeds, just run program instead of messing around with the path. In your code, that'd be like: if ! command -v program > /dev/null; then echo >&2 "Main Program not found"; else echo >&2 program; fi – muru Jan 16 '24 at 06:48
  • What does if $prog="" do? Have you tried it with various values of prog? Why do you say you can't use basename due to spaces in the paths? – ilkkachu Jan 16 '24 at 07:01
  • @ilkkachu: Iʻm checking whether there is anything left after trimming the directory part... – jarnosc Jan 16 '24 at 19:54
  • @muru: thatʻs the point: Iʻd like to know how get only the program name, without having to go all around the directory trimming after calling which, and avoiding the pitfall of a space in a path in a windoze directory with basename. – jarnosc Jan 16 '24 at 19:56
  • btw, chazelas is right: Iʻm just trying to check wheter program is available or not, to proceed accordingly... – jarnosc Jan 16 '24 at 20:07
  • But you already have the program name. – muru Jan 17 '24 at 00:21
  • indeed: the idea is to run these tests and tell the user what went wrong, if anything... – jarnosc Jan 17 '24 at 00:29
  • @jarnosz, ok, you don't have to answer the questions. – ilkkachu Jan 17 '24 at 06:56
  • for context: I was trying to run pdfroff, which is a shell script, on busybox on windoze, and the script could not find windoze's gswin64c because the path has a space in it. By inspecting the code, I found a baroque function searchpath() which does some checking, and reports installation errors to the user. For most *ix people this must be very weird, but makes sense as the script was designed to run on either OS, but not in a hybrid system. Now I see that hash does the job, and that the script needs indeed some simplification. – jarnosc Jan 17 '24 at 22:08
  • @jarnosz if that's all, then again: why do you need to manipulate the path to tell the user something went wrong? You'd only get the path if things didn't go wrong, and at that point you can just use the command name instead of the path. – muru Jan 18 '24 at 02:27
  • that's not all at all: at some point, the script has to query which version of GhostScript is running, and that depends on the OS (gs or gswin64c on modern machines, nix or win; but also gswin32c or even gsos2 for historical reasons: and I fear a similar check should be done with awk, as there are several implementations), so searchpath has to determine not only that the program exists, but also the name under which it is available... – jarnosc Jan 18 '24 at 17:24
  • Eh, what? You're using the name to find out where the program is, and then you turn around and say now you need to determine what that name was? – muru Jan 19 '24 at 04:45
  • as I said, it's not my code: I'm trying to patch this script. it also looks odd to me, so that's why I am asking how to avoid going all this weird way around: how to determine under which name a program is available, if any, to act accordingly, withouth having to strip the path. – jarnosc Jan 19 '24 at 20:22

1 Answers1

2

Looks like all you need is to check whether program is available as a command, then:

#! /bin/sh -
hash program || exit

use program now:

program with its args

I'm using hash instead of command -v > /dev/null as hash will report an error if program can't be found saving having to do it yourself. In any case, you don't want to use which.

  • how could I issue an error/warning or call a fallback procedure after the failure of hash program? afaik, exit will simply bail out without further ado. – jarnosc Jan 16 '24 at 20:05