简体   繁体   中英

What does it mean to “find a command in a path”?

This is an excerpt from the instructions of my homework for my operating systems class. The bolded portion is the part I cannot make sense of, nor can I reach the professor right now and I'd really like to start this tonight. I know what an environment variable is, I suppose...just a variable declared in the shell, right? But what does the bolded line in particular mean?

Write a C program to implement an interactive shell in which users execute commands.

Call this program myshell (so use gcc -o myshell -Wall etc. to compile).

Create an infinite loop that repeatedly prompts the user to enter a command (see example output and input below).

Before executing the command entered by the user, the command must be found using the path specified by environment variable THEPATH (do not use PATH!). By default, the THEPATH variable is not set, so for testing, you'll want to set (and unset) this variable manually (see details below). If THEPATH is found, your program must execute the command in a child process via fork() and one of the exec() system calls.

To obtain and parse THEPATH, consider using the getenv() function and the strtok() or strsep() functions.

For a shell to run a program, it has to know where that program is. For example, you want to be able to type ls at the prompt, but the actual binary for ls might be found at /bin/ls . That's where PATH (or your case, THEPATH ) comes in. When you type ls , the shell goes off and looks in each PATH directory for a program with a matching name. When it finds one, it runs it. Let's use ls as an example, and a PATH set to:

/usr/local/bin:/usr/bin:/bin

Assuming ls is /bin/ls , then the shell first looks for ls in /usr/local/bin , doesn't find it, then looks in /usr/bin , and then finally finds it in /bin and executes it.

Actually doing this operation is where the hint in your assignment about getenv , strtok , and strsep comes in.

Your variable THEPATH should contains a list of directories, separated by a colon, as in

THEPATH=/usr/bin:/bin:some-other-dirs

You must parse this into a list of directories. When the user enters a command, you must scan all the directories in order to find an executable whose name matches the command entered by the user.

Writing a shell at this level of sophistication is not a beginner task, and if you don't understand how the system's PATH handling works (you are just emulating what the shell does), you may be in over your head.

I know I'm late, but you can play a dirty trick here in the spirit of Master Foo's "gaining merit by not coding". The execlp() , execvp() and execvpe() C-library functions actually search the PATH variable for you. All you have to do is to replace PATH with your THEPATH in the environment. It makes your shell safer as well, because all your child processes will use your original THEPATH as PATH.

int i_path = -1;
int i_thepath = -1;
int i = 0;
while (envp[i] != NULL) {
    if (strstr(envp[i], "PATH=") == envp[i])
        i_path = i;
    if (strstr(envp[i], "THEPATH=") == envp[i])
        i_thepath = i;
    i++;
}
if (i_path >= 0 && i_thepath >= 0)
    envp[i_path] = envp[i_thepath] + 3; /* discard 'THE' */
else if (i_thepath >= 0)
    envp[i_thepath] = envp[i_thepath] + 3; /* discard 'THE' */
execvpe(command, argv, envp);

If you go for a manual parsing of THEPATH, do not create a list of directories. It's easy in a high level language like Perl, but involves manual dynamic memory allocation in C, because you don't know beforehand how many dir elements are there in THEPATH. And to do the memory allocation you need to iterate through the string first. But you can do the real job during the first iteration, using strtok() with ":" as the separator.

char *thepath = envp[i_thepath];
char *dir;
strtok(thepath, "="); /* first discard 'THEPATH=' */
while (dir = strtok(NULL, ":") {
    /* now check if dir+command exists and is execuatble, exec */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM