Search code examples
linuxbashshellcygwintcsh

tcsh script - Will not output simple ls -l command using cygwin


I want to check whether or not the files in a directory A match the files in directory B, and that these matched files are not modified/changed.

I am very new to this new programming environment as I am used to Windows. This task is a part of a school project but I am trying to run tcsh scripts on my Windows using cygwin and bash(?). However, i specify the tcsh environment in my scripts.

This simple script:

#!/usr/bin/tcsh
echo Hello world;

set listing=`ls -l`

echo $listing

Gives me the following output:

Shawn@Shawn-PC /cygdrive/c/Users/Shawn/Desktop
$ ./lab3.sh
Hello world
Unknown user: $372.

However, I am able to run the "ls -l" command directly into the command line and it returns the appropriate result, so I don't know why it can't execute my "ls -l" command in the script. I don't know if there something wrong with my tcsh syntax in the script and why it returns the error message "Unknown user: #372."


Solution

  • You probably have a file or directory whose name is something like ~372, or that contains that as part of its name.

    If you type

    echo ~372
    

    at the shell prompt, the shell will try to expand ~372 to the home directory of the user with the name 372. Almost certainly there is no such user -- thus the error message.

    Your command:

    set listing=`ls -l`
    

    isn't likely to be very useful anyway. The output of ls -l, which is line-oriented with aligned columns, will be joined into a single line of text with multiple blanks replaced by single blanks. It will be a mess, difficult to read. (Perhaps the point is to demonstrate this.)

    You can avoid the error on ~372 by adding double quotes around the backticks:

    set listing="`ls -l`"
    

    But now the string $listing contains that troublesome ~372, and if you try to echo it you'll have the same problem; $listing will expand to the string, and echo will try to expand the ~372 contained within it.

    So you also need to add quotes (or a :q suffix) to theecho` command.

    Here's what I got using tcsh on my system:

    % touch foo bar '~372'
    % ls -l
    total 0
    -rw-r--r-- 1 kst kst 0 Sep 19 14:06 bar
    -rw-r--r-- 1 kst kst 0 Sep 19 14:06 foo
    -rw-r--r-- 1 kst kst 0 Sep 19 14:06 ~372
    % set listing = `ls -l`
    Unknown user: 372.
    % set listing = "`ls -l`"
    % echo $listing
    Unknown user: 372.
    % echo "$listing"
    total 0 -rw-r--r-- 1 kst kst 0 Sep 19 14:06 bar -rw-r--r-- 1 kst kst 0 Sep 19 14:06 foo -rw-r--r-- 1 kst kst 0 Sep 19 14:06 ~372
    %
    

    This is not a particularly useful thing to do, but that's how to do it.

    Note that if you were using bash, then this:

    listing="`ls -l`"
    echo "$listing"
    

    would preserve the multi-line formatting.

    Obligatory link: http://www.perl.com/doc/FMTEYEWTK/versus/csh.whynot