How to execute linux console app without ./ - linux

Wow, let me first say that I've lost count how many answers I've found on this site. You guys are awesome!
So, my first-ever question I'm posting is rather basic so I hope it's not badly received. I did search to find an answer on google as well as here, but did not find an answer.
I just created a console app with code:blocks on linux, compiled it then ran within code:blocks. Works just fine. Then I opened linux bash shell, cd to where the binary was, then just tried running it from there, no dice. A linux buddy of mine came over and told me to try ./ preceeding it. Viola, that worked. I was dumbfounded because I thought ./ was only needed to execute shell scripts. I checked file permissions for the binary built by g++ and they are these: -rwxrwxr-x
I've found other tutorials on building the Hello World application with code:blocks and they also say to execute on the command line using ./
Why is this so? Also, how can I build a console application or any other binary application such that the ./ is not required to execute it? I'm assuming it's possible somehow seeing as the vast majority of the built-in linux commands, such as grep, etc do not require the ./ to execute.
Thanks, guys.

To run an executable on UNIX-like systems, you need to be aware of path resolution. If the path to the executable is not included in the PATH environment variable (and . sometimes isn't), you need to specify it yourself.
By appending . to PATH, like this:
export PATH=$PATH:.
you can run executables from the current working directory without adding ./. Note, however, this may be unsafe in a multi-user system, as other users can provide executables for you to run, in group or world writable directories, without your explicit permission(s).

Related

Application build . (Swift on Ubuntu)

I am a total newbie to programming and Ubuntu and Swift is my first language to learn.
I am learning with a book but I encountered a problem when I was supposed to build an application. Here is what I had to do:
Make a new directory called PMExample so that's easy mkdir PMExample
and then go to this directory cd PMExample.
Then I had to use ~/swift package init and got 2 directories called Sources and Tests and a file Package.swift.
So in the Sources folder there was one text file and I had to create another one to build an application.
And I did all those steps correctly, but now there is a problem. The book tells me to use swift build command. The book says that this will build the application and if all is well, I will have an executable application in the
PMExample/.build/debug directory named PMExample...
But after ~/swift build while being in the PMExample dir, there isn't any new directory called .build or anything. There are no errors popping up after using that ~/swift build command. Just nothing happens and I can't understand what am I doing wrong.
Thanks in advance.
But after ~/swift build while being in the PMExample dir, there isn't any new directory called .build or anything.
How do you know that? It is likely that you are not seeing the directory because it starts with a dot (it is called .build), therefore it is not shown by default with ls. You have to pass the -a argument to ls, such as in:
ls -a PMExample

multiple binaries with same name in ubuntu/linux

I have recently installed a webframework play (http://www.playframework.com/) and want to have the play executable in the system path ie $PATH. But ubuntu already defines a command called play. How do I overwrite the system defined command with my framework binary path so that command play on commandline calls my framework rather than the old application.
Installation: I downloaded zipped file of the framework and upzipped in one of my personal folder which contains the docs and the executable.
Never alter the contents of installed packages. Such changes can provoke hard to find problems in the system and anyway, they will most likely be overwritten again in subsequent updates. There are other alternatives:
obviously you can chose another name for your executable
place the executable in another part of your $PATH if its a "personal installation", typically ~/bin is used for such approach. Remember that the order of entries in the $PATH variable is important, first come first serve.
use the traditional /usr/local/bin location for locally added "wild" installations, this way there is some form of clean separation between clean packages and wild installed files inside the system
store your software in some other location and prepend that to your personal or system wide $PATH variable
store your executable under another name and create an alias (see man alias for an explanation) for it which allows to call it by some name that "hides" the original command this way. For this the executable can be addressed with an absolute path, so it dies not have to be found inside the $PATH variable.
In my personal opinion options 2. and 5. and the best if it comes to "personal installations".
If you are sure you'll never use the original play command, you could just remove the binary. But in general, this isn't a good idea, since some system component you don't think of might need it, and the next update will probably restore it.
The best thing to do is to prepend the directory of your play command to the PATH, for example, using PATH=/opt/framework/bin:$PATH in your .profile (assuming your play command installs to /opt/framework/bin/play), or the script that starts your web server, or wherever you need your play command.
Remember that does not make your play command global. A common mistake is to add the path in their .profile file, then call the program from crontab - crontab scripts will not execute .profile or .bashrc.

osx' s /etc/init.d equivalent?

I am installing gitlab on a mac but this latter is mainly designed for linux os. Following the doc, I have to run this command
curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab
What is the mac equivalent of the /etc/init.d folder (I know about the launchd command but I am looking for the mac's equivalent /etc/init.d folder) ?
AFAIK, launchd stores its data primarily in .plist files in /Library/LaunchAgents/ and /Library/LaunchDaemons/, and occasionally in those subdirectories in your home directory. More on those files in this tutorial and this reference.
For your problem specifically, to set launchd up to run gitlab, try converting that init.d script to a .plist file with the links above.
I don't know if you still care about the question or not, but what ryan said is correct. And to directly answer your question, your curl command is trying to download a startup script and put it into your init.d directory. You don't have one, as you are on Mac OS X.
What you need to do is pop that init.d somewhere else that is permanent. Make sure it is chmod +x and test to see if it works manually. (ie. ./init.d)
If it does, you can create a .plist and pop it into /Library/LaunchDaemons/ that will run your init.d file. If your init.d file is as simple as just running an executable, then forget the init.d file entirely, and just have the .plist file run the gitlab executable file directly.
Either way, I think that you should mark Ryan's (or mine as well) answer as Accepted, as it will solve your issue. The only reason I didn't put this as a comment on Ryan's answer is that my explanation was too long for a comment.
For a system with M1, it is stored in /sbin/launchd
It is differentiated with the PID 1

Advantage of $PATH over alias

I am relatively new to Linux and Unix. With the help of the internet I finally figured out how $PATH and aliases in my .bashrc work.
But I really couldn't find anything that describes when to use which.
Let's say I installed Python3.3 in Library/Frameworks and the executable is
/Library/Frameworks/Python.framework/Versions/3.3/bin/python3, but I want to execute python 3.3 just by typing python3 into my terminal.
When I understand it correctly, there are (at least) three methods to achieve this:
1) I modify $PATH in my .bashrc:
export PATH=/Library/Frameworks/Python.framework/Versions/3.3/bin:${PATH}
2) I set an alias in my .bashrc:
alias python3=/Library/Frameworks/Python.framework/Versions/3.3/bin
3) creating a symbolic link (symlink):
ln -s /Library/Frameworks/Python.framework/Versions/3.3/bin /usr/local/bin
What would you say (from your experience) is the "recommended" way?
Putting python3 in your path is the correct way to invoke it anywhere you might find yourself in your filesystem. A symbolic link is the best way to change that command to python and keep your scripts non version dependent (you can run a script that depends on python use the symbolic link and a script that needs python 3.0 specifically use python3, even though on your computer they are the same thing). Symbolic links are still files in your filesystem, so they still need to be in your path.
I only see aliases used when you are trying to create some kind of behavior that is different than the default behavior for a command line utility like an alias for ls that adds -a silently.
Also symbolic links are stored in the filesystem so once created they exist for all other users who log in, while aliases only apply to the logged in user who has defined them. They can also have file permissions applied to them.
Here is a fun article about things you can do to your terminal through your .bash_profile including some great aliases.
First, there is no reason to install Python in a /Library/Frameworks/ directory. My suggestion is that (at least for a beginner) you should not add top level directories like your /Library. If you compile it from source code, you should have built it with a standard ./configure (and it probably goes into /usr/local/)
I don't know well about compiling Python from source code, but most Linux source code gets by default ./configure-d to a /usr/local/ prefix so their binary go into /usr/local/bin/ which is often already by default in your PATH
Some Linux distributions have an /etc/profile which indirectly, if the directory $HOME/bin/ exists, adds it inside your PATH; in that case just adding binaries and scripts (or symbolic links) there is the most simple way.
My general advice is to avoid having a very long or very specific PATH. In particular, adding a directory inside your PATH for each product is IMHO a mistake. See e.g. the directory-variables section of GNU coding standards, and keep your PATH quite short. Personally I add programs only in /usr/local/bin/ (system-wide) or in $HOME/bin/, perhaps as symbolic links (so I don't change my PATH since it already contains both /usr/local/bin/ and $HOME/bin).
By past experience having a very long PATH is a nightmare, and slows down your interactive shells
Thank you all for your explanations.
As I already said, I am pretty new to Unix and Linux. I just wrote an article about those things (aliases, symlinks $PATH) for my blog for other "newbies". I like to write about those things, because they really interest me, and I want to share my experiences - I hope they are helpful to other people, too. Furthermore, it helps me to deepen my understanding if I have to explain things - and it is a good future reference, too!
It would be nice if you could skim over the article very quickly, and if I got some things wrong, I would be very happy about suggestions!
http://scientific-ocean.com/2013/02/17/an-introduction-to-linuxunix-executables-path-aliases-and-symlinks/
I would suggest go for alias which would make it easier for conflicts arising if you different versions of Python. The shell will look up the PATH variable and wherever it matches the executable of Python it will execute it. The alias has to be put in your shell profile like .bash_profile.

What should Linux/Unix 'make install' consist of?

I've written a C++ program (command line, portable code) and I'm trying to release a Linux version at the same time as the Windows version. I've written a makefile as follows:
ayane: *.cpp *.h
g++ -Wno-write-strings -oayane *.cpp
Straightforward enough so far; but I'm given to understand it's customary to have a second step, make install. So when I put the install: target in the makefile... what command should be associated with it? (If possible I'd prefer it to work on all Unix systems as well as Linux.)
Installation
A less trivial installer will copy several things into place, first insuring that the appropriate paths exists (using mkdir -p or similar). Typically something like this:
the executable goes in $INSTALL_PATH/bin
any libraries built for external consumption go in $INSTALL_PATH/lib or $INSTALL_PATH/lib/yourappname
man pages go in $INSTALL_PATH/share/man/man1 and possibly other sections if appropriate
other docs go in $INSTALL_PATH/share/yourappname
default configuration files go in $INSTALL_PATH/etc/yourappname
headers for other to link against go in $INSTALL_PATH/include/yourappname
Installation path
The INSTALL_PATH is an input to the build system, and usually defaults to /usr/local. This gives your user the flexibility to install under their $HOME without needing elevated permission.
In the simplest case just use
INSTALL_PATH?=/usr/local
at the top of the makefile. Then the user can override it by setting an environment variable in their shell.
Deinstallation
You also occasionally see make installs that build a manifest to help with de-installation. The manifest can even be written as a script to do the work.
Another approach is just to have a make uninstall that looks for the things make install places, and removes them if they exist.
In the simplest case you just copy the newly created executable into the /usr/local/bin path. Of course, it's usually more complicated than that.
Notice that most of these operations require special rights, which is why make install is usually invoked using sudo.
make install is usually the step that "installs" the binary into the correct place.
For example, when compiling Vim, make install may place it in /usr/local/bin
Not all Makefiles have a make install

Resources