I am programming a small unix shell written in c. I want it to do only some basic commands for now. e.g. ls, pwd, ch
My problem is how do I set the Home directory and Path directory? I want to read the configuration from a text file so it can be easily changed whenever.
I am going to be using execv() to call unix functions such as ls. For example PATH
should determine the directories my shell should use to search for executable programs
when the user types a command
Thanks
They are all simply environment variables that you manipulate e. g. through setenv(3) (run man 3 setenv for details). The variables are HOME and PATH. See also man 7 environ.
Note that setting/changing an environment variable only influences the current process and all processes forked from it after the setting/changing (unlike in Windows, AFAIK).
Check out the function setenv. See man 3 setenv for information about it.
Unix already offers you an environmental variable that contains all the paths where system executables are stored. Retrieve the variable in your code with getenv("PATH"); Each path is separated with a ':' so all you need to do is tokenize and begin searching those paths for the executable your command wants to run. In this function you should also be able to search any path of your choosing for an executable.
You can decide what directory you want to start in ("home directory" as you say) by manipulating the current working directory before the shell prompts with chdir(). You can also use that unix function for implementing a cd command that can be used throughout the run time of the shell.
Related
Say I made and compiled a small program in C to count the bytes of a file, called filebyte. To run it I would use ./filebyte
Now I want to make it universal on bash, like for example to run a php file, I would use bash command php file.php, same way I would like to run my program, filebyte filename.
How do I do this?
Thanks!
I often create a bin/ directory in my home directory, for small custom applications.
You then need to add that directory to your PATH, which is a list of colon-separated paths that your shell searches for executables when you type a name on thr command line.
This is usually accomplished by putting this in your ~/.bashrc file:
PATH="$PATH:~/bin"
Check the environment variable PATH and put the executable in one of the directories listed. You can also put it in a custom directory and then append it to PATH. You can check it by executing printenv PATH
If you want it for your current active shell alone, do
export PATH=$PATH:</path/to/file>
For permanently making the file available add the above line to ~/.bashrc
Why add it in PATH variable, man bash says why,
PATH The search path for commands. It is a colon-separated list of
directories in which the shell looks for commands (see COMMAND
EXECUTION below). A zero-length (null) directory name in the
value of PATH indicates the current directory. A null directory
name may appear as two adjacent colons, or as an initial or
trailing colon. The default path is system-dependent, and is set
by the administrator who installs bash. A common value is
''/usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin''.
In Operating System concept i want to write a C program to make Unix command works as DOS commands.
It Means when ever i press Unix Command like ls -which is used for Display list of Files- it works like Dir command in DOS.Could you please help me out with this?
Starting with the ls command as example, take input from user for the command. If the command is ls call a windows function that will display the content of the current working directory(). For ls,
you need to get first the current working directory. GetCurrentDir() for windows will be your first step. This will help How do I get the directory that a program is running from?
Then you can list the files in directory like this https://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(v=vs.85).aspx. But you do need the output of first step.
Other commands can also be implemented like this
I want to run an executable found in ../folder1/folder2 while inside of a C script. Right now I'm trying to do:
char command[50];
strcpy(command, "cd ../folder1/folder2");
system(command);
memset(command,0,sizeof(command));
strcpy(command, "./executable_name");
system(command);
but it's not working. Should I be using chdir(), or is there another way to do this? Is it even possible?
It's not working because when you execute:
system("cd ../folder1/folder2");
it does not have an effect on the current directory of the executable. Hence, when you execute:
system("./executable_name");
it doesn't find it.
You can solve it using any of the following methods:
Change the command given to system:
system("../folder1/folder2/executable_name");
Change the command given to system:
This is going to work if your default shell is bash, and many of the UNIX shells.
system("cd ../folder1/folder2; ./executable_name");
Create a shell script that has:
#/bin/bash
cd ../folder1/folder2
./executable_name
and then run the shell script from C using system
system("myscript.sh");
Add a line to chdir in C before you call system:
chdir("../folder1/folder2");
system("./executable_name");
Update, Thanks due to #Jongware
All of the above assume that your program is executed in a directory from where ../folder1/folder2 is a valid path. If your program is executed from a different directory and you want to account for that scenario, you have to parse argv[0] and adjust the way you handle the calls to execute executable_name.
The simplest way is normally:
system("../folder1/folder2/executable_name");
Failing that, you have to either do the cd via chdir() in your program, or arrange to do the cd and execute the command in a single shell (single call to system()), as in:
system("cd ../folder1/folder2; ./executable_name");
The problem is that system, does a fork, executes the cd in a sub-process, which ends and does not effect the working directory of the program process. Shells, need to make cd & dirs builtins for them to have an effect.
Rather than use a shell command, you can use getwd and chdir to change directory then system with "." as you tried, add a "cd ../folder1/folder2; ./executable_name", use fork and change directory and run the command in the child with exec yourself, or alternatively just run the program using the relative path "../folder1/folder2/executable_name".
#include <unistd.h>
int chdir(const char *path);
char *getcwd(char *buf, size_t size);
You need to execute a script that changes the directory then runs the application.
You can simply execute a program using a relative or absolute path. If you actually want to execute it in another working directory, read on.
Currently your program does not change its working directory before executing the child program.
Simply explained, system starts a new program which changes its working directory and then exits, so your program is not affected.
What you tried works in actual scripts because the interpreter does not spawn a new shell for each command you give it, but executes them itself.
Use chdir() or some other API for changing the directory of the currently executing program.
I've a executable named say "sortx". Now I want to write a C program which transforms this executable into a shell command.
ex:
./sortx numbers.txt
After running the C program on "sortx" what I want is :
sortx numbers.txt
Add the directory in which sortx is present to $PATH. This way you could execute your program locally, like,
sortx numbers.txt
To add directory ~/my_bin to the beginning of the $PATH environment variable, add or update this in your .bash_profile:
PATH=~/my_bin:$PATH
On Linux to make any script or program globally executable (e.g "sortx" rather than "./sortx") you can put the script in wither /usr/bin or /bin -- I prefer /usr/bin :)
I/O Redirection
Advanced Shell Topics: stdin, stdout and redirection
I am having a situation for which I am looking for some suggestion.
Suppose I write a program which prints the directory names of the directories.
Is it possible to convert this program into a command (just on my system).
Not be alias but via C only.
As long as the file is executable (has the exec x access for the user starting it) and can be seen from the command interpreter (usually bash or sh), you can consider it to be a command.
There will be no difference in running your own file from your path than the ls command for instance.
Also, the C (or C++ ...) language is not a requirement. There are plenty of commands in, for instance, /usr/bin that are a script, meaning they're sh or bash (or even perl)...
access Ensure the file has the x access right (e.g. chmod u+x file)
path Ensure the file is in your PATH, or add an entry in your path (for instance) with PATH=$PATH:mypath
test Test it well before to put it in a path from which other users may have access
Put it in the path. On Linux, for example, you should put it in /usr/local/bin.
First, compile the program and create an executable using gcc program.c -o myexecfile. Then, an executable file named myexecfile is created in the same directory. You can run it by using ./myexecfile.
If you are on Unix(Linux etc.) and want to use it like ls or any other standard command, you need to place it in a directory that is specified in $PATH variable. For example, /usr/local/bin.