Linux command file for symbolic links - linux

when I try to check the type of an executable file, I always get this:
symbolic link to <another_file>
Then I have to dig further and run file <another_file>. Sometimes this could take 5 or 6 rounds. I'm wondering whether there is a way to let file to recursively go to the original file and tell me the file type.

Specifying -L to file should make it follow symlinks. From the man page:
-L, --dereference
option causes symlinks to be followed, as the like-named option
in ls(1) (on systems that support symbolic links). This is the
default if the environment variable POSIXLY_CORRECT is defined.

use "file -L" to follow symbolic links

Related

Find out the path to the original file of a hard link

Now, I get the feeling that some people will think that there was no original file of a hard link, but I would strongly disagree because of the following experiment I did.
Let's create a file with the content pwd and make a hard link to a subfolder:
echo "pwd" > original
mkdir subfolder
cp -l original subfolder/hardlink
Now let's see what the files output if I run it with shell:
sh original
sh subfolder/hardlink
The output is the same, even though the file hardlink is in a subfolder!
Sorry, for the long intro, but I wanted to make sure that nobody says that my following question is irrelevent.
So my question now is: If the content of the original file was not conveniently pwd, how do I find out the path to the original file from a hard link file?
I know that linux programs seem to know the path somehow, but not the filename, because some programs returned error messages that <path to original file>/hardlinkname was not found. But how do they do that?
Thanks in advance for an answer!
Edit: Btw, I fixed the error messages mentioned above by naming the hard links the same as the original file.
But how do they do that?
By looking for the same inode value. Here's one way you can list files with the same inode:
find /home -xdev -samefile original
replace /home with any other starting directory for find to start searching.
how do I find out the path to the original file from a hard link file?
For hard links there are no multiple files, just one file (inode) with multiple (file) names.
ADDENDUM:
is there no other way to find the hard links of an inode than searching through folders?
ln, ls, find, and stat are the common ways of discovering and querying the filesystem for inodes. Then depending on what next you want to accomplish, many file, directory, archiving, and searching commands recognize inode values. Some may require a special -inum or --follow or equivalent option to specify inodes.
The find example I gave above is just one such usage. Another is to combine with xargs to operate on all the found files. Here's one way to delete them all:
find /home -xdev -samefile original | xargs rm
Look under --help for other standard os commands. Most Linux distributions also come with help files that explain inodes and which tools work with inodes.
pwd is the present working directory, so of course, the output should be the same, since you didnt cd't into your subfolder.
Sorry to say, but there is no "original" file if you create other hardlinks. If you want to get other hardlinks of a file, look at How to find all hard links to a given file? for example.
Agree with #Emacs User. Your example of pwd is irrelevant and confused you.
There is no concept of original file for hard-links. The file names just act as a reference count to the content on the disk pointed by the i-node (see 'ls -li original subfolder/hardlink'). So even if you delete the original file hardlink still points to the same content.
It is impossible to find out as all hard links are treated the same way pointing to one inode.

need to include a new file with 'diff' utility as a patch

When doing "diff -bBupwr" of two directories, dir and dir.orig to capture the differences, the util doesn't include files that exist only in dir, it only reports that e.g. dir/app.c exists only in dir/, but I would like it to be added in a resulting diff file, so that it could be applied as a patch.
I checked 'man diff' but no clues was found. I'd appreciate helpful advises for this. Thanks.
Use the option -N. The man page says:
-N, --new-file
treat absent files as empty

Linux: Man command in application installed only for current user

Manual files in Linux are stored in /usr/share/man. Before, my application could only be installed by a root user and it put the manual files in this directory. Now, I want to enable non-root installation; to achieve this, all my data and configuration files will be installed under ~/<appname>/. However, manual files copied to home will no longer be accessible by man command.
What are the usual workarounds to this problem?
I've thought in creating a "man" command in my application that runs man -M /<man_path>/<appname>/ (as this is easier to users than running the command by themselves). Is this a good option?
Thanks in advance.
[spatel#ap4004 appname]$ export MANPATH=/home/spatel/appname/man
[spatel#ap4004 appname]$ manpath
/home/spatel/appname/man/en:/home/spatel/appname/man
Other workaround is command alias
[spatel#ap4004 appname]$ alias man='man -M /home/spatel/appname/man'
[spatel#ap4004 appname]$ alias man
alias man='man -M /home/spatel/appname/man'
You'll need to use manpath command.
man has new behaviour by default (at least on Fedora 14 and on) that it searches in paths corresponding to PATH environment variable, i.e. for PATH=/xyz/bin it searches /xyz/bin/man, /xyz/share/man and other nearby places. Unless MANPATH is set.
You need to unset MANPATH at the end of your .bash_profile, some startup scripts in /etc may set it to spite you.
If you don't specify an explicit path list with -M or MANPATH, man develops its own path list based on the contents of the configuration file /etc/man.config. The MANPATH statements in the configuration file identify particular directories to include in the search path.
Furthermore, the MANPATH_MAP statements add to the search path depending on your command search path (i.e. your PATH environment variable). For each directory that may be in the command search path, a MANPATH_MAP statement specifies a directory that should be added to the search path for manual page files. man looks at the PATH variable and adds the corresponding directories to the manual page file search path. Thus, with the proper use of MANPATH_MAP, when you issue the command man xyz, you get a manual page for the program that would run if you issued the command xyz.
In addition, for each directory in the command search path (we'll call it a "command directory") for which you do not have a MANPATH_MAP statement, man automatically looks for a manual page directory "nearby" namely as a subdirectory in the command directory itself or in the parent directory of the command directory.
You can disable the automatic "nearby" searches by including a NOAUTOPATH statement in /etc/man.config.

Doubt regarding executable files in linux

I have a program written in C, which is named computeWeight.c and to compile it i use the following code
chaitu#ubuntu:~$ gcc -Wall -o computeWeight computeWeight.c
//to execute it:
chaitu#ubuntu:~$ ./computeWeight
Do i have any mechansim where i can directly use as mentioned below,
chaitu#ubuntu:~$ computeWeight
Should i be changing any permissions on the executable to get this?
You need to add "." to your path. Some people regard this as dangerous, though. See for instance http://www.arsc.edu/support/policy/dotinpath.html .
The $PATH variable define the places where linux would look for executables (try typing echo $PATH in a terminal). You need to put that file in one of those places. One way is to add a bin folder in your home directory, put the executable file there, and add this line (which adds the bin directory in your home folder to the search path) to your .cshrc file so that it'd be executed for every shell:
set PATH = ($PATH $HOME/bin)
With that said I don't think typing ./ is that bad.
export PATH=$PATH:.

Setting bash command-line variable to start my application

I'm pretty new to programming for Linux environments, so I don't exactly know what to search for in order to answer this question for myself. I need to understand how applications set the shell to accept a certain command to start them. For example, you can start Firefox from the command line by executing the command: firefox.
I don't know where this is defined. Makefile? Configure script? In the source code itself?
Any resources / reading on Linux programming tidbits like these would be greatly appreciated!
Thank you.
Firefox is launched by the command "firefox" because there is an executable file in one of the folders in the $PATH environment variable called "firefox".
Are you talking about the PATH variable? It seems like you are.
In linux, you should be able to type: "echo $PATH" (without quotes) and get a ":"-separated list of locations where programs are located (like firefox).
If you need to add something to your path, you should be able to do:
export PATH=$PATH:/another/directory
In your shell (which is most likely bash)
You can also type:
which firefox
To display the location of the firefox executable.
Typically the shell is going to have an environment variable called $PATH set. This is just an ordered list of all the directories to look when somebody types in a command. As soon as it finds an executable file (by which I mean a file for which you have execute permissions, not a file ending in .exe) with the same name as whatever was typed, it will run that file. Common directories in $PATH might be /bin, /usr/local/bin, ~/bin, etc.
So, when you type 'firefox', the shell looks through all the directories in $PATH until it finds /usr/local/bin/firefox, which it then runs. To make your own programs run the same way, you'll either need to put them (or a symbolic link to them) in a directory that is likely to be in every user's path (/usr/local/bin/ is a good choice), or you'll need to get your users to add your program's directory to their $PATH.
For a more complete description, see the Wikipedia article about the $PATH variable.
As an alternative to the modification of $PATH mentioned earlier, you could also copy or link your executable in one of the directories already in your $PATH. more specifically, /usr/local/bin/ is available on most UNIX system for pretty much this purpose (installing software outside the default package management of the operating system).
It has to be in the path as everyone else mentioned, but you might also need to make it executable with something like this:
chmod +x /path/to/file
And if it's a script there's usually a shebang at the top that tells the os what to use to execute it:
#! /usr/bin/python
Often, large packages are installed in /opt with a wrapper script or link somewhere in the PATH. For example, on my system, Google Picasa is installed in /opt/google/picasa and there is a symlink at /usr/bin/picasa to /opt/google/picasa/3.0/picasa
Firefox is at /usr/bin/firefox on my system and that's a symlink to /usr/bin/firefox-3.0 which is itself a symlink to /usr/lib/firefox-3.0.11/firefox.sh - That shell file fumbles around until it finally runs /usr/lib/firefox-3.0.11/firefox (unless it finds a reason to do something else). That, finally, is a binary executable. So /usr/lib is where firefox is installed, for me.
You can use this command to find out where a program is:
type -a firefox
Then, you can find out what kind of file it is using this:
file /usr/bin/firefox
Also see the Filesystem Heirarchy Standard for more information about recommended locations for files and programs.

Resources