2013-10-26 7 views
0

Я пытаюсь написать сценарий оболочки «echo.by», который повторяет его аргументы столько раз, сколько пользователь выбирает. Например, если пользователь вводит в командной строкеUNIX Shell Scripting Output

echo.by 5 Play it again, Sam. <return> 

Сценарий должен напечатать

Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 
Play it again, Sam. 

Однако, я не знаю, как печатать только Play это снова, Сэм и исключить первый аргумент. $* команда печатает все, так что я в конечном итоге с

5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 
5 Play it again, Sam. 

Мой сценарий должен быть в состоянии удовлетворить любой сценарий после первого числа, так что я не могу просто сказать оболочке эхо $2 $3 $4 $5.

Вот мой сценарий:

count = 0 
while test $count -lt $1 
do 
echo $* 
count = `expr $count + 1` 
done 
+0

FYI - 'счетчик = 0' работает программа' count' с аргументами '= 'и' 0'. Если вы хотите выполнить задание, вам необходимо оставить пробел: 'count = 0'. Кроме того, '((count ++))' гораздо проще писать, чем 'count = $ ((count + 1))' (опять же, без пробелов вокруг '='). –

+0

... также - котировки; использовать их. 'echo '$ *" ', а не' echo $ * '. Если кто-то передал в ваших аргументах «*», вы бы не захотели, чтобы его заменили на список файлов в текущем каталоге, не так ли? Угадайте, что произойдет, если вы не процитируете свои аргументы ... –

ответ

2

Просто поместите $1 в переменной, которая будет ссылаться позже, а затем добавить shift в верхней части вашего сценария.

+1

Это, наверное, лучший ответ здесь с точки зрения правильности. Считали добавление образца кода? –

1
#!/bin/bash 
times="$1" 
shift 
for f in $(seq "$times"); do 
    echo "[email protected]" 
done 

EDIT: Изменено $times быть строчную как предложено @Charles Даффи. Для большей совместимости с другими системами POSIX (например) вы можете изменить цикл, чтобы использовать C-style for -syntax. Команда seq доступна в системах NetBSD, FreeBSD и GNU.

+2

'seq' не является стандартным инструментом POSIX. Лучше использовать цикл 'for' для C-стиля, поскольку вы уже указываете' bash', а не POSIX sh. 'for ((i = 0; i <$ 1; i ++)); do ... ' –

+0

Да, это действительно справедливая точка. –

+0

Отредактировано соответственно. (Также перемещается в имя переменной нижнего регистра - по соглашению, all-caps должны быть зарезервированы для переменных среды и встроенных функций, чтобы избежать конфликтов пространства имен). –

1

Попробуйте сделать это, используя стиль C для контура и среза массива:

#!/bin/bash 

for ((i=0; i<$1; i++)); do 
    echo "${@:2:${#@}}" 
done 
0
#!/bin/bash 
times="$1" 
shift 
for ((f=0; f<times; i++)); do 
    printf '%s\n' "$*" 
done 
+0

Почему накладные расходы на использование 'printf' и форматированной строки, а не просто' echo'ing ввода? –

+0

@ AdamLiss 'printf' не накладные расходы - это встроенная оболочка, такая же, как и эхо; его преимущество над эхом (помимо гибкости, предлагаемой форматированными строками) является более последовательное поведение на разных платформах - POSIX неоднозначно по поводу того, использует ли echo опции, тогда как printf ведет себя одинаково на всех платформах. –

+1

@AdamLiss ... для конкретного примера случая, когда 'echo' будет делать не то, учтите' echo.by 5 -n'; версия 'printf' будет корректно печатать' -n' пять раз; версия 'echo' ничего не будет печатать в системе, которая выбирает реализацию' echo -n'. –

Смежные вопросы