I have to write a module that sends a command to the system.
For example: The "ls" command, as you know, is a common bash command.
Since I am new at this module thing, I need some help.
As far as I know, ls is no bash builtin command.
You can call any program (for example ls) with the complete path (/usr/bin/ls).
Related
My teacher gave us this assignment to create our own shell. Our shell is supposed be called rshell and is supposed to work like the regular shell.
I created my own shell using C++. If you type a command like ls in my created shell it gives you a list just like how if you typed ls in the regular shell.
The problem I am facing is how do I get the .sh files or script files to work with my created shell. I noticed when I run a .sh file using my shell it does not run the .sh file through my shell. It runs it through the regular shell. How do I make .sh files run through my shell?
Change the hash-bang line of the scripts to point at your shell. For instance,
#!/usr/local/bin/rshell
Or wherever your shell executable is.
As John already said, change the shebang to point to your shell. The kernel will invoke the command in the shebang with the file itself as an argument. To demonstrate, try a file with a shebang of #!/bin/cat.
#!/bin/cat
hello world
It pretty much behaves the same as if you typed /bin/cat /path/to/file.
The shebang does not have PATH lookup capabilities, so #!yourshell would not work as a shebang. However, you can use env to do the PATH lookup as in #!/usr/bin/env yourshell. (This approach is preferred for commands that are at different paths on different systems, like python.)
My shell-script is failing on SUSE Linux as the stream-redirection operator I have used (&>>) is not working there, (But it is working fine in Other distributions). How can I correct this. Also I would like to know the standard way of doing the same which is supported by all Distributions?
The command you were using should mean you were using bourne shell:
ls &>> file
this command should redirect both stdout and stderr at the end of file.
Another way to write it, again with a bourne shell could be:
ls >> file 2>&1
However it seems to me this way to write the command will be recognized by more shells, I think for instance ksh will recognize the second form but not the first.
With csh or a csh-like shell you will need to use this syntax:
ls >>& file
Edit: I was confused because depending on the shell you can use &>> or >>& which are not the same.
This is a pretty simple one... I just want to make a perl script executable without the preceding perl command, and instead let the environment deduce the interpreter from the shebang line. Here is my sample script called test:
#!/usr/bin/perl
print "Hey there\n";
I then use chmod 775 test to make the script executable. If I use the command perl test, I get the output Hey there.
However, if I just type test, I get no output. What's the deal? Why isn't my shebang line making the environment realize this is perl? Can someone please help me?
Don't name your script test. This is a built-in command in most shells, so they don't go looking for an external program.
Also, to run a program in your current directory, you should type ./programname. It's generally a bad idea to have . in your $PATH, which would be necessary to execute it without the directory prefix.
To run something from the current directory you need to prefix "./" to tell it "this directory" ie ./testprogram.
If you type just test it will look in standard install directories like /bin. This is why when you run cp or rm it knows where the executable is.
As mentioned by others, naming scripts test is not allowed with most shells.
I was wondering if there is a way to get Linux commands with a perl script. I am talking about commands such as cd ls ll clear cp
You can execute system commands in a variety of ways, some better than others.
Using system();, which prints the output of the command, but does not return the output to the Perl script.
Using backticks (``), which don't print anything, but return the output to the Perl script. An alternative to using actual backticks is to use the qx(); function, which is easier to read and accomplishes the same thing.
Using exec();, which does the same thing as system();, but does not return to the Perl script at all, unless the command doesn't exist or fails.
Using open();, which allows you to either pipe input from your script to the command, or read the output of the command into your script.
It's important to mention that the system commands that you listed, like cp and ls are much better done using built-in functions in Perl itself. Any system call is a slow process, so use native functions when the desired result is something simple, like copying a file.
Some examples:
# Prints the output. Don't do this.
system("ls");
# Saves the output to a variable. Don't do this.
$lsResults = `ls`;
# Something like this is more useful.
system("imgcvt", "-f", "sgi", "-t", "tiff", "Image.sgi", "NewImage.tiff");
This page explains in a bit more detail the different ways that you can make system calls.
You can, as voithos says, using either system() or backticks. However, take into account that this is not recommended, and that, for instance, cd won't work (won't actually change the directory). Note that those commands are executed in a new shell, and won't affect the running perl script.
I would not rely on those commands and try to implement your script in Perl (if you're decided to use Perl, anyway). In fact, Perl was designed at first to be a powerful substitute for sh and other UNIX shells for sysadmins.
you can surround the command in back ticks
`command`
The problem is perl is trying to execute the bash builtin (i.e. source, ...) as if they were real files, but perl can't find them as they don't exist. The answer is to tell perl what to execute explicitly. In the case of bash builtins like source, do the following and it works just fine.
my $XYZZY=`bash -c "source SOME-FILE; DO_SOMETHING_ELSE; ..."`;
of for the case of cd do something like the following.
my $LOCATION=`bash -c "cd /etc/init.d; pwd"`;
I have just started using Linux and I am curious how shell built-in commands such as cd are defined.
Also, I'd appreciate if someone could explain how they are implemented and executed.
If you want to see how bash builtins are defined then you just need to look at Section 4 of The Bash Man Page.
If, however, you want to know how bash bultins are implemented, you'll need to look at the Bash source code because these commands are compiled into the bash executable.
One fast and easy way to see whether or not a command is a bash builtin is to use the help command. Example, help cd will show you how the bash builtin of 'cd' is defined. Similarly for help echo.
The actual set of built-ins varies from shell to shell. There are:
Special built-in utilities, which must be built-in, because they have some special properties
Regular built-in utilities, which are almost always built-in, because of the performance or other considerations
Any standard utility can be also built-in if a shell implementer wishes.
You can find out whether the utility is built in using the type command, which is supported by most shells (although its output is not standardized). An example from dash:
$ type ls
ls is /bin/ls
$ type cd
cd is a shell builtin
$ type exit
exit is a special shell builtin
Re cd utility, theoretically there's nothing preventing a shell implementer to implement it as external command. cd cannot change the shell's current directory directly, but, for instance, cd could communicate new directory to the shell process via a socket. But nobody does so because there's no point. Except very old shells (where there was not a notion of built-ins), where cd used some dirty system hack to do its job.
How is cd implemented inside the shell? The basic algorithm is described here. It can also do some work to support shell's extra features.
Manjari,
Check the source code of bash shell from ftp://ftp.gnu.org/gnu/bash/bash-2.05b.tar.gz
You will find that the definition of shell built-in commands in not in a separate binary executable but its within the shell binary itself (the name shell built-in clearly suggests this).
Every Unix shell has at least some builtin commands. These builtin commands are part of the shell, and are implemented as part of the shell's source code. The shell recognizes that the command that it was asked to execute was one of its builtins, and it performs that action on its own, without calling out to a separate executable. Different shells have different builtins, though there will be a whole lot of overlap in the basic set.
Sometimes, builtins are builtin for performance reasons. In this case, there's often also a version of that command in $PATH (possibly with a different feature set, different set of recognized command line arguments, etc), but the shell decided to implement the command as a builtin as well so that it could save the work of spawning off a short-lived process to do some work that it could do itself. That's the case for bash and printf, for example:
$ type printf
printf is a shell builtin
$ which printf
/usr/bin/printf
$ printf
printf: usage: printf [-v var] format [arguments]
$ /usr/bin/printf
/usr/bin/printf: missing operand
Try `/usr/bin/printf --help' for more information.
Note that in the above example, printf is both a shell builtin (implemented as part of bash itself), as well as an external command (located at /usr/bin/printf). Note that they behave differently as well - when called with no arguments, the builtin version and the command version print different error messages. Note also the -v var option (store the results of this printf into a shell variable named var) can only be done as part of the shell - subprocesses like /usr/bin/printf have no access to the variables of the shell that executed them.
And that brings us to the 2nd part of the story: some commands are builtin because they need to be. Some commands, like chmod, are thin wrappers around system calls. When you run /bin/chmod 777 foo, the shell forks, execs /bin/chmod (passing "777" and "foo") as arguments, and the new chmod process runs the C code chmod("foo", 777); and then returns control to the shell. This wouldn't work for the cd command, though. Even though cd looks like the same case as chmod, it has to behave differently: if the shell spawned another process to execute the chdir system call, it would change the directory only for that newly spawned process, not the shell. Then, when the process returned, the shell would be left sitting in the same directory as it had been in all along - therefore cd needs to be implemented as a shell builtin.
A Shell builtin -- http://linux.about.com/library/cmd/blcmdl1_builtin.htm
for eg. -
which cd
/usr/bin/which: no cd in (/usr/bin:/usr/local/bin......
Not a shell builtin but a binary.
which ls
/bin/ls
http://ss64.com/bash/ this will help you.
and here is shell scripting guide
http://www.freeos.com/guides/lsst/