devise a script that takes a filename as argument (which must exist in current directory) and locates from your home directory tree all pathnames of its links. The list should be mailed to self. I have tried this, but I dont know what exactly script wants..

echo. "enter file name"
read name
if [ $name == "a1.txt" ]; then
source a1.txt
/* a1.txt file contents tree -l */
  • Why do you have to enter the file name, if a1.txt is the only name allowed? And did you look at man find if you want to locate files in a directory tree? I'm afraid I don't understand what exactly you expect the script to do. – Philippos Apr 21 '17 at 12:00
  • 1
    This is looks very much like homework. We don't do that here. – schaiba Apr 21 '17 at 12:06
  • Hint: Try man [ and the -f bit. And another hint: if [ -f "$1" ]. – Tigger Apr 21 '17 at 12:13

Ok, let's break this down into bits:

  1. Take a filename as an argument
  2. Make sure that the file exists (and is a regular file)
  3. Find all (symbolic) links to the file under $HOME
  4. Mail this list of files to $LOGUSER

A script may take an argument (or several). The command line arguments are available in the positional parameters $1, $2 etc. Since we only will get one argument, we're only concerned with what's in $1.


To test whether a name exists, we may use

if [ -e "$name" ]; then ... fi

In this case, we're interested in testing whether a name does not exist:

if [ ! -e "$name" ]; then
   echo 'Name does not exist in directory' >&2
   exit 1

Since we're outputting a diagnostic message (an error message in this case), we're doing so to the standard error stream by redirecting the output from echo with >&2. We also terminate the script with a non-zero exit status to signal that something went wrong.

If we want to make sure that the file not only exists, but also that it's a regular file, i.e. not a directory or a device node or something else, change -e to -f (read the test manual).

To find all symbolic links in our home directory, we may use

find "$HOME" -type l

With either of bash or ksh93 we may look at these files and compare them with the file we've been given by the user using

if [[ "$name" -ef "$link" ]]; then ... fi

where $name would be $1 and $link would be the name of the symbolic link returned from find. The -ef operator will return a true value if the two operands refer to the same file (after resolving all symbolic links).

One may combine the find with the above test like this:

find "$HOME" -type l |
while read -r link; do
    if [[ "$name" -ef "$link" ]]; then
        printf '%s\n' "$link"

To send an email, use the mail command. This may be tagged on to the end of the previous pipeline:

find "$HOME" -type l |
while read -r link; do
    if [[ "$name" -ef "$link" ]]; then
        printf '%s\n' "$link"
done |
mail -s "These are the links" "$LOGUSER@localhost"

$LOGUSER will hold your username. Use "$(id -un)" if $LOGUSER for some reason is not set properly, or just replace the whole string with whatever email address you'd like to use.

  • bt after executions it said @ localhost ...user address required and email saved to dead.letter – Avinash Utekar Apr 23 '17 at 22:06
  • @AvinashUtekar Well, you may use whatever email address you wish there. – Kusalananda Apr 23 '17 at 22:17
  • i wrote like this .. mail -s "These are the links" "Avi@localhost" but it sends to dead.letter – Avinash Utekar Apr 23 '17 at 22:31
  • @AvinashUtekar Use a valid email address, one that you know works. If that doesn't work, make sure your system has an MTA ("mail transfer agent") installed, like postfix or exim or similar. If that's a problem, please submit that as a new question. – Kusalananda Apr 23 '17 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.