Run binary with ./ in Ubuntu - linux

I decided to learn C++ (I program in C at work), and I have been reading some tutorials (and lots of posts here on Stack Overflow). OK, so I typed in the standard C++ "hello word", compiled with GCC on my Ubuntu machine as "test".
Then I tried to run it by typing "test" and hitting enter. Nothing. It turns out I must run it with "./test". OK, fine, I'll do that from now on. But why? The "./" just says that what I should run is in the current directory... Is the current directory not always part of the PATH when the OS is searching for something to run? Can I make it so?

Yes, the current directory is not part of your PATH. You don't want it to be, because then you could be in a directory that had a malicious program you didn't know about that you run.
What if you were used to running /usr/bin/grep, but you happened to be in a directory that a Bad Person put a malicious copy of grep in, and this time you run grep, and you're running grep out of the current directory, rather than /usr/bin/grep.
You certainly can add ./ to your PATH in your ~/.profile or ~/.bash_profile, but I don't recommend it.
And if it makes you feel any better, I had the same frustration 15 years ago when I started using Unix-like systems.

You can add "." to your PATH, but that won't help you in this case - "test" is a shell built in.

Unfortunately, there is a Unix command called "test"...

If there's a command line script you regularly run, you could set up a command line alias to rid yourself of the need to type ./ each time.

Even if the current directory is at the very beginning of the $PATH, 'test' still won't run it on (most?) shells, as 'test' is a shell built-in command.

Not having '.' (the current directory) in the PATH is a minor security measure. You could always add it in if you'd like, though it's not a best practice.

In case it's not clear, this is an aspect where Windows differs from Unix/Linux. On Windows, the current directory is implicitly in the path.

Related

cd(Change Directory) command on linux

I am trying to code on Colab and if I take a look at the code its self similar with linux, therefore I am asking how the commands work on linux.
I am still confused the why cd on linux works. If I have code like this
cd A/B
it means to create new directory right?
after the first code then I write this
!wget https://abcd.com
does it mean I download file from https://abcd.com and store it at B path?
cd does not create anything, it just changes your shell's current working directory.
The ! in your next command is a bit weird, too. It indicates a history expansion of the most recent command line in your shell history starting with wget, adding https://abcd.com to that command line and then running it. That could be pretty much anything, depending on what your shell history contains.

How to make a fish script executable in any directory?

I made the switch to Ubuntu a couple of months ago and still do not have very much experience with unix and fish aside from the basic/often used commands. For a C class that I am taking I constantly need to SSH onto a remote linux machine run by my university called Zeus. The command to ssh onto it is a bit lengthy, and I would like to be able to make the process faster with a fish script.
I wrote a file called "zeus.fish" that essentially just calls my ssh command, among a few other things. Currently I can only run it by calling "fish zeus.fish" within the directory of the file. I would like to be able to run the script from within any directory, just like any other command. IE just typing "zeus" would attempt to log me into the remote machine. I'm assuming that I have to do something with PATH. How can I do this? Thanks!
You can make an executable and put it somewhere in $PATH. However, the simplest thing is to make a zeus function. A fish function is like a function in other languages: some named block of code.
Run this: function zeus; your_long_command_goes_here ; end
Run funcsave zeus to save it permanently
Now zeus will run that command.
What this does is put a file zeus.fish in ~/.config/fish/functions/. You can also do that manually of course.
I think this should work.
Add this to the first line of the script:
#!/bin/fish
That way it knows to execute your script with fish. Otherwise you would have to use ./scriptname or fish scriptname, to indicate you wanted fish to execute it.
Remove the .fish ending, if you want to call it just by "zeus".
Add the file to your path. In your .fishrc, write:
export PATH=XXX:$PATH
Okay, so I've never used fish. Apperently they don't use .fishrc, put it into your equivalent of .bashrc. Which is ~/.config/fish/config.fish as far as I can see. Actually the line you have to write is
set -x PATH $PATH XXX
With XXX being the path to your file, for example copy it into a folder named bin in your home directory. Then it would be
set -x PATH $PATH $HOME/bin
Last but not least, make the file executeable by writing:
chmod +x FILENAME
It seems like an alias would be a simpler solution for you however.
In your fish equivalent of .bashrc, you can do:
function zeus
ssh username#server
end
This seems to be the fish equivalent of an alias. If it is just 1 line that is long, you could do it like this. Having the line inside the function. Now you could just call "zeus" from anywhere aswell.
ridiculous_fish's answer is (obviously) entirely correct, but actually complicating it a bit in my opinion.
funced zeus; and funcsave zeus
will do the same thing in one go, launching an (empty) interactive function definition prompt in the first command, instantly saving it when editing finishes. If there is already a function of that name it will show up in the editor, so it's easy to continuously tweak your functions without having to dive into (or even consider the existence of) your fish config dir.
One of the very first functions I made when picking up the shell was "func", that makes exactly those two calls (since I only rarely edit a function without the intention of saving my changes)
For simple ssh stuff and other oneliners that don't take any input or where the input ($argv) is sure to just be appended at the end of the line,
alias zeus='ssh ...'; and funcsave zeus
will do the same. Any further editing will have to go through funced though.

"ls" command works sometimes and sometimes doesn't on Node.js

Please help me out, i am new. "ls" command for list doesn't work on my Node.js most times. It is not working now. However, it works sometimes though. How can i find list of current directory or file in Node.js?
As per to my tutorial for Node.js, i have to use command "ls" to see the list of my current directory or file.
When i press enter on ""ls" it replied "ls" is not found as internal or external command."
However, "ls" command shows the contents of file sometimes. I am using "ls" command for Desktop listing and another file in their. I do go to Desktop by cd Desktop. and then i only write "ls" then enter.
Please reply with simple explanation since i am new and learning Node.js.
i am taking Essential Node.js training from Lynda.com. "ls" did worked earlier though. "ls" does work on Window Shell and Bash all the time. Please reply. Thank You.
If not, what command i shall use for listing current directory or file contents?
Windows operational system provides the command dir instead of ls which should work similarly in your case:
Just use:
dir

What's a .sh file?

So I am not experienced in dealing with a plethora of file types, and I haven't been able to find much info on exactly what .sh files are. Here's what I'm trying to do:
I'm trying to download map data sets which are arranged in tiles that can be downloaded individually: http://daymet.ornl.gov/gridded
In order to download a range of tiles at once, they say to download their script, which eventually leads to daymet-nc-retrieval.sh: https://github.com/daymet/scripts/blob/master/Bash/daymet-nc-retrieval.sh
So, what exactly am I supposed to do with this code? The website doesn't provide further instructions, assuming users know what to do with it. I'm guessing you're supposed to paste the code in to some other unmentioned application for a browser (using Chrome or Firefox in this case)? It almost looks like something that could be pasted in to Firefox/Greasemonkey, but not quite. Just by a quick Google on the file type I haven't been able to get heads or tails on it.
I'm sure there's a simple explanation on what to do with these files out there, but it seems to be buried in plenty of posts where people are already assuming you know what to do with these files. Anyone willing to just simply say what needs to be done from square one after getting to the page with the code to actually implementing it? Thanks.
What is a file with extension .sh?
It is a Bourne shell script. They are used in many variations of UNIX-like operating systems. They have no "language" and are interpreted by your shell (interpreter of terminal commands) or if the first line is in the form
#!/path/to/interpreter
they will use that particular interpreter. Your file has the first line:
#!/bin/bash
and that means that it uses Bourne Again Shell, so called bash. It is for all practical purposes a replacement for good old sh.
Depending upon the interpreter you will have different languages in which the file is written.
Keep in mind, that in UNIX world, it is not the extension of the file that determines what the file is (see "How to execute a shell script" below).
If you come from the world of DOS/Windows, you will be familiar with files that have .bat or .cmd extensions (batch files). They are not similar in content, but are akin in design.
How to execute a shell script
Unlike some unsafe operating systems, *nix does not rely exclusively on extensions to determine what to do with a file. Permissions are also used. This means that if you attempt to run the shell script after downloading it, it will be the same as trying to "run" any text file. The ".sh" extension is there only for your convenience to recognize that file.
You will need to make the file executable. Let's assume that you have downloaded your file as file.sh, you can then run in your terminal:
chmod +x file.sh
chmod is a command for changing file's permissions, +x sets execute permissions (in this case for everybody) and finally you have your file name.
You can also do it in your GUI. Most of the time you can right click on the file and select properties; in XUbuntu the permissions options look like this:
If you do not wish to change the permissions, you can also force the shell to run the command. In the terminal you can run:
bash file.sh
The shell should be the same as in the first line of your script.
How safe is it?
You may find it weird that you must perform another task manually in order to execute a file. But this is partially because of a strong need for security.
Basically when you download and run a bash script, it is the same thing as somebody telling you "run all these commands in sequence on your computer, I promise that the results will be good and safe". Ask yourself if you trust the party that has supplied this file, ask yourself if you are sure that you have downloaded the file from the same place as you thought, maybe even have a glance inside to see if something looks out of place (although that requires that you know something about *nix commands and bash programming).
Unfortunately apart from the warning above I cannot give a step-by-step description of what you should do to prevent evil things from happening with your computer; so just keep in mind that any time you get and run an executable file from someone you're actually saying, "Sure, you can use my computer to do something".
If you open your second link in a browser you'll see the source code:
#!/bin/bash
# Script to download individual .nc files from the ORNL
# Daymet server at: http://daymet.ornl.gov
[...]
# For ranges use {start..end}
# for individul vaules, use: 1 2 3 4
for year in {2002..2003}
do
for tile in {1159..1160}
do wget --limit-rate=3m http://daymet.ornl.gov/thredds/fileServer/allcf/${year}/${tile}_${year}/vp.nc -O ${tile}_${year}_vp.nc
# An example using curl instead of wget
#do curl --limit-rate 3M -o ${tile}_${year}_vp.nc http://daymet.ornl.gov/thredds/fileServer/allcf/${year}/${tile}_${year}/vp.nc
done
done
So it's a bash script. Got Linux?
In any case, the script is nothing but a series of HTTP retrievals. Both wget and curl are available for most operating systems and almost all language have HTTP libraries so it's fairly trivial to rewrite in any other technology. There're also some Windows ports of bash itself (git includes one). Last but not least, Windows 10 now has native support for Linux binaries.
sh files are unix (linux) shell executables files, they are the equivalent (but much more powerful) of bat files on windows.
So you need to run it from a linux console, just typing its name the same you do with bat files on windows.
Typically a .sh file is a shell script which you can execute in a terminal. Specifically, the script you mentioned is a bash script, which you can see if you open the file and look in the first line of the file, which is called the shebang or magic line.
I know this is an old question and I probably won't help, but many Linux distributions(e.g., ubuntu) have a "Live cd/usb" function, so if you really need to run this script, you could try booting your computer into Linux. Just burn a .iso to a flash drive (here's how http://goo.gl/U1wLYA), start your computer with the drive plugged in, and press the F key for boot menu. If you choose "...USB...", you will boot into the OS you just put on the drive.
How do I run .sh scripts?
Give execute permission to your script:
chmod +x /path/to/yourscript.sh
And to run your script:
/path/to/yourscript.sh
Since . refers to the current directory: if yourscript.sh is in the current directory, you can simplify this to:
./yourscript.sh
or with GUI
https://askubuntu.com/questions/38661/how-do-i-run-sh-scripts/38666#38666
https://www.cyberciti.biz/faq/run-execute-sh-shell-script/
open the location in terminal then type these commands
1. chmod +x filename.sh
2. ./filename.sh
that's it

Strange "sh" behaviour

I am developing an application on Beaglebone board with Angstrom distrubition fo Linux.I faced an interesting problem.
When I execute :
sh /home/root/Desktop/BBTCP/out/vehicleDetect 192.168.10.29
in terminal it says
/home/root/Desktop/BBTCP/out/vehicleDetect: /home/root/Desktop/BBTCP/out/vehicleDetect: cannot execute binary file
But when i execute
cd /home/root/Desktop/BBTCP/
and
sh out/vehicleDetect 192.168.10.29
it starts working??
What is the reason and why I can't run tha application with first configuration?
I think it is about the difference between ./ and sh. What are the differences?
My first guess would be that one of the folders in the path /home/root/Desktop/BBTCP is a link. If vehicleDetect is a script and it invokes itself recursively, then this link might be confusing it.
If that's not the case, try sh -x /home/root/Desktop/BBTCP/out/vehicleDetect and see what that prints.
Lastly, check what's in the folder /home/root/Desktop/BBTCP. There might be an executable sh in there. If your path contains ., a different shell might be executed.
Seems like /home/root/Desktop/BBTCP/out/vehicleDetect is invoking a binary file (an executable) that was built on a different architecture.
The main difference between sh and ./ is that ./ will attempt to execute the file itself as an executable, whereas sh will do that for you. It could be that there is a weird magic number at the start of the file, but you would expect sh to complain about that.
Best guess though it is a #! line at the start of the file which either contains invalid characters or refers to a strange file. Did you, for example, bring this script file from another operating system (like Windows) that has different line endings? I have seen similar effects when text file scripts have not been converted but just copied. Maybe you downloaded it in a strange format?
Check with od -xc /home/root/Desktop/BBTCP/out/vehicleDetect and look at the first line.

Resources