Моя конечная цель состоит в том, чтобы выполнить итерацию по всем параметрам, используемым в последней командной строке в bash, чтобы найти любой путь к каталогу. Пример того, что я хотел бы:Параметры командной строки Split bash умным и чистым способом
$ cp some_file.txt /some/existing/folder; touch a_new_file.txt
$ my_find_func
Found "/some/existing/folder" in the last command.
Моя проблема заключается в расщеплении последнюю команду в правильном направлении, для того, чтобы обрабатывать все возможные случаи. Теперь я использую что-то вроде этого:
function myfunc()
{
last_com="$(history|tail -n2|head -n1|sed -n 's/^\s*[0-9]*\s*//p')"
eval "args=($last_com)"
# Note: I don't care about the security issue that eval can cause
for arg in "${args[@]}"; do
echo "$arg"
done
}
Мне нравится простота использованияeval
таким образом, потому что он обрабатывает автоматически цитируемые параметры, спасся пространство, расширение Глобо и т.д ... Так что я не должен сам справиться со сложной командой awk
или sed
.
Он отлично работает с отдельными командами, например:
/afac/soq $ cd ..
/afac $ myfunc
cd
..
/afac $ touch "some file.txt"
/afac $ myfunc
touch
some file.txt
Но очевидно (из-за «» внутри определения массива), он терпит неудачу, когда я использую несколько команд в одной строке:
$ touch a_file; rm a_file
$ myfunc
bash: syntax error near unexpected token ';'
$ touch a_file && rm a_file
$ myfunc
bash: syntax error near unexpected token '&&'
Итак, чтобы сделать его работу, я бы, чтобы разбить командную строку на части, когда ;
, &&
или ||
встречается, не забывая при этом случай, когда эти маркеры экранируются или цитировал, а затем прощались с простота ... Я даже не знаю, если я могу еще разобрать это в хорошем смысле, с нынешних знаний у меня есть о sed
и awk
...
Что бы самым чистым (и самое простое) решение, чтобы получить все параметры команды в массив, обрабатывая возможность цитируемых параметров, экранированных символов, и нескольких команд в одной строке?
Возможно, это совсем не дубликат, но я нигде не нашел никакого реального решения.
Итак, каково ожидаемое содержимое вашего массива 'args' в таких командах:' echo '1 2 3' && echo "AB" C' –
@Eugeniu Rosca: что-то вроде '(echo '1 2 3' '&& 'echo "AB" C) 'или' (echo' 1 2 3 'echo "AB" C) '.Важно то, что каждый эффективный параметр присутствует, так что я могу проверить их с помощью некоторой вещи, например '[[-d $ {args [$ i]}]]' в цикле – yolenoyer
Вместо 'eval 'args = ($ last_com) ", попробуйте' IFS = '' args = ($ last_com) ' –