Сценарій оболонки: створення змінної з параметрами всередині


11

У мене є команда rsync з такими параметрами:

rsync -avz --{partial,stats,delete,exclude=".*"}

Я хочу помістити ці параметри всередині змінної, щоб повторно використовувати її в скрипті. Щось на зразок цього:

#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2

Я намагався з цитатами, одинарними цитатами, дужками, без жодного успіху.


Схожий питання на SO: stackoverflow.com/questions/13365553 / ...
Barmar

Збившись з цього маршруту раніше: Переконайтеся, що в останньому командному рядку в ньому немає порожніх рядків. Якщо це так, rsync може використовувати їх як параметри, і оскільки вони невидимі, налагодити це досить важко. У мене був порожній перший параметр, і rsync інтерпретував його як включення поточного каталогу у джерела речей, які потрібно скопіювати.
Джо

Відповіді:


12

Введення складної команди у змінну - це ніколи не рекомендований підхід. Дивіться BashFAQ / 050 - я намагаюся поставити команду в змінну, але складні випадки завжди не вдається!

Ваша вимога стає дійсно простою, якщо ви просто вирішите використовувати функцію замість змінної та передаєте їй аргументи.

Щось на зразок

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --{partial,stats,delete,exclude=".*"} "$@"
}

а тепер передайте йому необхідні аргументи як

rsync_custom /dir1 /dir2

Визначення функції є певним чином простим, спочатку перевіряємо кількість вхідних аргументів за допомогою змінної, $#яка не повинна бути нульовою. Ми кидаємо повідомлення про помилку, вказуючи, що аргументи не наводяться. Якщо є дійсні аргументи, то "$@"представляє фактичні аргументи, подані до функції.

Якщо це функція, яку ви використовуєте досить часто, тобто в скриптах / командному рядку, додайте її, наприклад, до файлів запуску оболонки .bashrc, .bash_profileнаприклад.

Або, як зазначалося, можливо, варто розширити розширення дужок на окремі аргументи для кращої читабельності як

rsync_custom() {
    [ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
    rsync -avz --partial --stats --delete --exclude=".*" "$@"
}

5
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

Це намагається запустити команду -avzз аргументами --partialі --statsт. Д. І з VARналаштуваннями rsyncв оточенні.

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

Цитована форма не працює, тому що дужки не розширюються в лапках, а не всередині призначення, а також не розширюються після розширення змінної.

Якщо вам потрібно зберегти аргументи командного рядка у змінній, використовуйте масив:

args=(rsync -avz --{partial,stats,delete,exclude=".*"})

Тепер "${args[@]}"буде розширюватися rsync, -avz, --partialі т.д. , як окремі слова.

Масиви також дозволяють додавати параметри до списку, за умови, за необхідності, так що ви можете:

args=(this that)
if something ; then
    args+=(another_arg)
fi
"$cmd" "${args[@]}"

1

Ви можете принаймні зберегти параметри частково у змінній:

opts=$(echo --{ignore-case,word-regexp,count,exclude='"sys*.*"'})

Тестування важливо, оскільки маскування може бути важким:

echo $opts
--ignore-case --word-regexp --count --exclude="sys*"

grep $opts bytes *.log 

Оскільки існує декілька альтернатив, таких як використання історії, використання псевдоніма, використання функції, я не маю очевидних випадків використання, про які я можу придумати. Рідко існує складний варіант спільного доступу між різними програмами, тому для спеціального рішення інтерактивної оболонки псевдонім здається кращим способом:

alias cgrep='grep --ignore-case --word-regexp --count --exclude="sys*"'
cgrep bytes *.log

Ваш зразок

VAR=rsync -avz --{partial,stats,delete,exclude=".*"}

не може працювати, тому що призначення є ендетом на першому бланку. Ви повинні замаскувати заготовки:

VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'

досить небезпечна річ для тестування, з цим варіантом - видалити, чи не так? Оскільки параметри можуть знову містити "," та одиничні лапки, маскування може скластись дуже швидко. Я б пішов на псевдонім або покладався на історію.

Псевдонім може бути збережений у файлі ~ / .bashrc для постійного використання протягом декількох сеансів. Функції можуть бути збережені і в bashrc, але вони вам потрібні лише, якщо ви хочете обробляти параметри, передані в функцію, яка оцінюється в ній.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.