bash/csh — вывести строки $#argv и #!/bin/csh

Я пытаюсь создать csh на лету с другим csh скриптом, echo загрузив кучу операторов в другой файл и запустив его.

Но я не могу повторять такие строки, как "$#argv" и "#!/bin/csh"

Первый всегда анализируется генератором csh в его значение #argv, а shebang просто выдает ошибку, говорящую Event not found. Есть ли способ, которым я мог бы повторить это в файл?

Я согласен с генератором csh вместо bash, но выходной скрипт должен быть csh, так как он использует целую кучу переменных среды csh.

PS - я пробовал echo -e и пытался добавлять обратную косую черту везде, где мог, но тщетно. Это также не сработало при использовании одинарных кавычек вместо двойных.


person Vivek V K    schedule 16.02.2017    source источник
comment
Переменные среды на самом деле не относятся к какой-либо одной оболочке. Если переменная находится в вашей среде, она будет в среде любого дочернего процесса (и если этот дочерний процесс является оболочкой, доступной как переменная, предполагая, что имя является допустимым идентификатором).   -  person chepner    schedule 16.02.2017
comment
@chepner Я этого не знал! Спасибо.   -  person Vivek V K    schedule 16.02.2017


Ответы (2)


csh — аналогично POSIX-подобным оболочкам — использует строки в одинарных-кавычках ('...') для буквальных строк (строки которые не подлежат расширению оболочки) — в отличие от двойных строк в кавычках ("..."), в которых ссылки с префиксом $ расширяются (интерполируются, мгновенно ).

Следовательно, должна работать следующая команда:

% echo '$#argv'
#argv

Однако интерпретация ! — функция истории команд — предшествует даже обычным расширениям оболочки, и поэтому требуется дополнительный уровень экранирования с помощью \ :

% echo '#\!/bin/csh'
#!/bin/csh

Кроме того, опять же, как и в POSIX-подобных оболочках, вы можете смешивать стили цитирования в непосредственно смежных токенах, чтобы формировать единый, составной строка:

% set arg = 3
% echo 'if($#argv < '"$arg"') then'
if($#argv < 3) then

Обратите внимание, как только $arg было расширено (интерполировано) из-за того, что (единственная часть) была заключена в "...".

В данном конкретном случае сработало бы и не заключенное в кавычки использование $arg, но обратите внимание, что использование не заключенных в кавычки (под)строк, содержащих метасимволы шаблона (например, * и ?) — опять же, как в POSIX-подобных оболочках — делает (всю) строку подлежащей подстановке (расширению имени файла) .

person mklement0    schedule 16.02.2017
comment
Потрясающее объяснение. Спасибо! - person Vivek V K; 16.02.2017
comment
@VivekVK: С удовольствием; рад, что это было полезно. - person mklement0; 16.02.2017

Вы можете использовать echo с побегами, чтобы получить этот вывод из csh:

echo '$#argv'
echo '#\!/bin/csh"

согласно следующей расшифровке:

% cat testprog.csh
echo '$#argv'
echo '#\!/bin/csh'

% csh testprog.csh
$#argv
#!/bin/csh
% 
person paxdiablo    schedule 16.02.2017
comment
Благодарность! Ваш тестовый пример работает, но не работает, когда я использую его следующим образом: echo "if('$#argv' < $arg ) then" где $arg — это локальная переменная, которую необходимо заменить ее значением, а $#argv — нет. - person Vivek V K; 16.02.2017