Copyright © 1996-2019,2022 by Thomas E. Dickey

CONFLICT – List filename-conflicts


conflict displays conflicting filenames in your execution path. Unlike the csh command which, it displays all of the conflicting (non-alias) executable filenames in your path.


I wrote this in 1988, based on a script that I wrote while at the ITT Advanced Technology Center to analyze execution-path and environment conflicts on VM/SP CMS. Since then, I've added the ability to scan for different types of conflicts (e.g., along an include-path for C compilers).

I wrote the original script in 1982, in EXEC2, to help troubleshoot problems that I encountered in sharing my XEDIT macros with other developers. With CMS, the potential for naming conflicts was different from Unix-style systems. There were two dimensions:

In short, the script analyzed the user's environment to report naming conflicts which would interfere with a script's operation.


Oddly, this tool is not widely used. There are no comparable programs (so it is not simply a case of faring badly with competition). Rather, almost all discussion in the technical area deals with setting one's PATH environment variable.

Programs to update PATH

I wrote one of those in June 1994, called newpath. Here is its usage summary, to give a flavor:

Usage: newpath [options [directories]] [ - command]

Echos the PATH environment variable with the given directories added
(the default) or removed.

    -a NAME modify path after given NAME
    -b      put new arguments before existing path
    -d      remove duplicates/non-directory items
    -e      put new arguments after end of path
    -f      allow filenames to match, as well as directories
    -n NAME specify environment-variable to use (default: PATH)
    -p      print in C-shell form
    -r      remove arguments from path
    -v      verbose

Put a '-' before a command which is invoked with the environment variable
updated, rather than echoing the result to standard output.

That is a compiled executable. But again, most activity in the area has a different focus, e.g., shell functions (rather than compiled applications) which do some of the features which my application does. I wrote newpath initially as a shell script, and rewrote it as a C program for that reason. The reason why I wrote newpath was that in the project where I was working, we used NFS-mounted home directories on a variety of Unix servers (SunOS 4.1.3, Solaris 2.3, IRIX 5.3 and 6, etc.), which had different tools available for each environment. My .cshrc file set a variable to a list of the possible directories, newpath tested those once and produced a workable PATH. Here is an example from my current .cshrc:

# pick up extra entries from local ncurses, override existing ones
foreach dir ( /usr/lib/terminfo /usr/share/terminfo /usr/share/lib/terminfo /usr/local/ncurses/lib/terminfo /usr/local/ncurses/share/terminfo )
        setenv TERMINFO_DIRS `newpath -bdfn TERMINFO_DIRS -fbd $dir ${dir}.db`

Others had similar ideas—implemented as shell functions. The first which I have seen was part of pdksh in its port to OS/2 (e.g., July 1994). This chunk from /etc/profile illustrates the idea:

# simple versions. See ksh.kshrc for the clever ones
add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"}
pre_path () { [ -d $1 ] && eval ${2:-PATH}="$1:\$${2:-PATH}"}
del_path () { eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: | 
        sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`}

A much later (more elaborate) variant can be found here.

Programs to analyze PATH

As shell functions are slow, they are necessarily less ambitious than conflict. At the same time as newpath, I wrote a cut-down variant of conflict, path as a script:

For a single file of interest, path and conflict give similar results. I wrote this as a stopgap while awaiting approval to bring in sources for my tools (mainly ded).

Later, I considered making a version of newpath for Windows, but put that idea aside (because the approach would necessarily have been more cumbersome). Some people (see this have done useful work in that area.

Still, there are a few scripts which do some part of the functionality of conflict. Here is a link to an example (also named “checkpath”) which prints a report. For example, here is the beginning of its (rather long and verbose) report on my machine:

Path directories, in search order

1: /usr/local/bin
2: /users/tom/bin
3: /users/tom/com
4: /usr/sbin
5: /sbin
6: /usr/bin
7: /bin
8: /usr/games
9: .
10: /usr/lib/vile

RCS not found in $PATH
install-info has 2 conflicts
0: -rwxr-xr-x 1 root root 5896 Apr 30 09:24 /usr/sbin/install-info
1: -rwxr-xr-x 1 root root 1216 Oct 14  2010 /usr/bin/install-info

   /usr/sbin/install-info: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
   /usr/bin/install-info: POSIX shell script text executable

linklint has 2 conflicts
0: -r-xr-xr-x 1 tom users 131417 Jan  6 04:18 /users/tom/bin/linklint
1: -rwxr-xr-x 1 root root 131327 Jan 23  2008 /usr/bin/linklint

   /users/tom/bin/linklint: a /usr/bin/perl -- # -*- perl -*- script text executable
   /usr/bin/linklint: a /usr/bin/perl -- # -*- perl -*- script text executable

That is the default output. There is a terse mode which prints the names and the number of conflicts. Here is a comparable section of the report from conflict which shows where the conflicts come from, and whether they are due to identical (linked) files or different files. Incidentally the report citing “RCS” is bogus, since it is a symbolic link to a directory.

Current working directory is "/users/ftp/pub/dickey/conflict"
-> /usr/local/bin
--> /users/tom/bin
---> /users/tom/com
----> /usr/sbin
-----> /sbin
------> /usr/bin
-------> /bin
*----*-: bye
---*-*-: dpkg-divert
---*-*-: dpkg-statoverride
-----**: dumpkeys
---*-+-: install-info
---*-*-: install-menu
----*-*: ip
-----**: ksh
-----**: less
-----**: lessecho
-----**: lessfile
-----**: lesskey
-----**: lesspipe
-*---+-: linklint

Likewise, this unnamed Python script uses a verbose approach to the problem. It is not a general-purpose tool however, since it requires an XML file as input.

Another example, pathfinder, is a little less verbose primarily by collapsing the information for each name onto a single line. Aside from that, it is not an improvement over the first “checkpath” script:

RCS in /users/tom/com is shadowed by /users/tom/bin
run-linklint in /users/tom/com is shadowed by /users/tom/bin
setup-kde in /users/tom/com is shadowed by /users/tom/bin
umount.hal in /sbin is shadowed by /usr/sbin
bye in /usr/bin is shadowed by /usr/local/bin
copyrite.txt in /usr/bin is shadowed by /users/tom/bin
dpkg-divert in /usr/bin is shadowed by /usr/sbin
dpkg-statoverride in /usr/bin is shadowed by /usr/sbin
install-info in /usr/bin is shadowed by /usr/sbin
install-menu in /usr/bin is shadowed by /usr/sbin
linklint in /usr/bin is shadowed by /users/tom/bin

Besides a less-verbose report, the feature which I use in conflict is absent from each of these examples: the ability to construct a list of pathnames for analysis. I pipe the output of conflict into ded and get the timestamp and size information in a sortable display, for free.

The Windows and OS/2 port of conflict shows a different report than the POSIX one. That is because there may be more than one executable using the same name in a directory, differing only by type. Here is an example:

Current working directory is "C:\"
:----:----> C:\WINDOWS
:----:----:----> C:\COM
:-E--:-E--:----: EXPLORER (.EXE)
:-E--:-E--:--B-: HH (.EXE,.BAT)
:-E--:-E--:----: NOTEPAD (.EXE)
:-E--:-E--:----: REGEDIT (.EXE)
:-E--:-E--:----: WRITE (.EXE)
The “B” and “E” markers on the left denote the file types which are expanded on the right, The “.BAT” and “.EXE” Technically, the permissable types are enumerated in the environment variable PATHEXT. However, I have not (yet) modified conflict to use this information because it would involve some rethinking of the fairly compact report. It would be very wide if each type had a column. Use your imagination:

Again, with Windows, others have had the same problem, with most of the attention being on making the PATH readable. Here are a few links to relevant discussion:


See the changelog for details: