Сценарий tcsh - не будет выводить простую команду ls -l с использованием cygwin

Я хочу проверить, соответствуют ли файлы в каталоге A файлам в каталоге B и что эти совпадающие файлы не изменены/изменены.

Я новичок в этой новой среде программирования, так как привык к Windows. Эта задача является частью школьного проекта, но я пытаюсь запустить сценарии tcsh в своей Windows, используя cygwin и bash(?). Однако я указываю среду tcsh в своих скриптах.

Этот простой скрипт:

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

set listing=`ls -l`

echo $listing

Дает мне следующий вывод:

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

Однако я могу запустить команду «ls -l» непосредственно в командной строке, и она возвращает соответствующий результат, поэтому я не знаю, почему она не может выполнить мою команду «ls -l» в сценарии. Я не знаю, есть ли что-то не так с моим синтаксисом tcsh в сценарии и почему он возвращает сообщение об ошибке «Неизвестный пользователь: # 372».


person shawn a    schedule 19.09.2014    source источник
comment
tcsh очень плохая оболочка для написания скриптов, обязательно так делать?   -  person Barmar    schedule 19.09.2014
comment
Будет ли работать лучше, если вы закавычите переменную echo "$listing"?   -  person Barmar    schedule 19.09.2014
comment
К сожалению, это инструмент разработки, который мы обязаны использовать для заданий. Нет, я получаю точно такой же вывод, когда использую echo $listing   -  person shawn a    schedule 19.09.2014
comment
Кроме того, если я изменю список на =date, он отлично выведет команду даты. Почему у него проблемы с ls?   -  person shawn a    schedule 19.09.2014
comment
Вероятно, в выводе ls -l есть специальный символ. Попробуйте set listing = "`ls -l`"   -  person Barmar    schedule 19.09.2014
comment
Нет, тогда вместо строки Неизвестный пользователь: $372. пишет 'ls-l'   -  person shawn a    schedule 19.09.2014
comment
Должно быть, это проблема cygwin, потому что я только что запустил этот скрипт на компьютере с Linux в моей школе, после предоставления скрипту соответствующих разрешений он отлично работал с ожидаемым выводом ls -l.   -  person shawn a    schedule 19.09.2014
comment
@shawna: Вероятно, потому что у вас не было файла с ~ в имени.   -  person Keith Thompson    schedule 20.09.2014


Ответы (2)


Вероятно, у вас есть файл или каталог с именем, похожим на ~372, или который содержит это как часть своего имени.

Если вы наберете

echo ~372

в приглашении оболочки оболочка попытается расширить ~372 до домашнего каталога пользователя с именем 372. Почти наверняка такого пользователя нет — отсюда и сообщение об ошибке.

Ваша команда:

set listing=`ls -l`

все равно вряд ли пригодится. Вывод ls -l, ориентированный на строки с выровненными столбцами, будет объединен в одну строку текста с заменой нескольких пробелов одним пробелом. Это будет беспорядок, трудно читать. (Возможно, смысл в том, чтобы продемонстрировать это.)

Вы можете избежать ошибки на ~372, добавив двойные кавычки вокруг обратных кавычек:

set listing="`ls -l`"

Но теперь строка $listing содержит этот проблемный ~372, и если вы попытаетесь echo, у вас будет та же проблема; $listing будет расширяться до строки, а echo попытается расширить содержащуюся в ней ~372.

Поэтому вам также нужно добавить кавычки (или команду :q suffix) to theecho`.

Вот что я получил, используя tcsh в своей системе:

% 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
%

Это не особенно полезная вещь, но вот как это сделать.

Обратите внимание, что если вы использовали bash, то это:

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

сохранит многострочное форматирование.

Обязательная ссылка: http://www.perl.com/doc/FMTEYEWTK/versus/csh.whynot

person Keith Thompson    schedule 19.09.2014

Если вам просто нужно распечатать на терминале, то это все, что вам нужно.

#!/usr/bin/env tcsh

echo Hello world

ls -l

Если вам нужно сохранить его как массив или что-то еще, было бы проще вывести его в текстовый файл, а затем прочитать его построчно как массив. (Интервал перепутался для меня, чтобы сделать это напрямую).

#!/usr/bin/env tcsh

echo Hello world

ls -l > output.txt

Если это то, что вам нужно, прочитайте об импорте текстового файла в виде массива.

Кроме того, это было бы намного проще в bash, если бы у вас был выбор.

person PhysicalChemist    schedule 19.09.2014