Присвоения, как и в var=foo*
, не расширяют globs - то есть, когда вы запускаете var=foo*
, буквальная строка foo*
помещается в переменная foo
, а не список файлов, соответствующих foo*
.
Напротив, некорректное использование foo*
в командной строке расширяет глобус, заменяя его списком отдельных имен, , каждый из которых передается как отдельный аргумент .
Таким образом, запуск ./yourscript foo*
не проходит foo*
как $1
, если нет файлов, соответствующих этому выражению glob; вместо этого он становится чем-то вроде ./yourscript foo01 foo02 foo03
, причем каждый аргумент находится в другом месте в командной строке.
Причина, по которой работает ./yourscript "foo*"
, является обходным путем - это неупомянутое расширение внутри скрипта, позволяющее glob в дальнейшем. Однако это плохая практика: расширение glob происходит параллельно с расщеплением строк (это означает, что использование этого поведения устраняет вашу способность передавать имена файлов, содержащие символы, найденные в IFS
, обычно пробелы), а также означает, что вы не можете передавать литералы имена файлов, когда они также могут быть интерпретированы как глобы (если у вас есть файл с именем [1]
и файл с именем 1
, передача [1]
всегда будет заменена на 1
).
Идиоматический способ построения этого будет состоять в том, чтобы shift
отпустить первый аргумент, а затем перебрать последующие, например:
#!/bin/bash
out_base=$1; shift
shopt -s nullglob # avoid generating an error if a directory has no .status
for dir; do # iterate over directories passed in $2, $3, etc
for file in "$dir"/*.status; do # iterate over files ending in .status within those
grep -e "string" "$file" # match a single file
done
done >"${out_base}.extension"
Если у вас много файлов .status
в одном каталоге, все это можно сделать более эффективным, используя find
для вызова grep
с максимально возможным количеством аргументов, а не для вызова grep
отдельно для каждого файла :
#!/bin/bash
out_base=$1; shift
find "$@" -maxdepth 1 -type f -name '*.status' \
-exec grep -h -- /dev/null '{}' + \
>"${out_base}.extension"
Оба сценария выше предполагают, что глобы не передавались в вызывающую оболочку. Таким образом, использование имеет форму:
# being unquoted, this expands the glob into a series of separate arguments
your_script descriptor dir_*_map
Это значительно лучше, чем передача globs в ваш скрипт (который затем должен расширять их для получения фактических файлов для использования); он корректно работает с именами, содержащими пробелы (которые другая практика не делает), и файлы, имена которых сами являются глобус-выражениями.
Некоторые другие примечания:
"$dir"/*.status
, то завершите кавычки до начала выражения glob. for dir; do
точно эквивалентен for dir in "$@"; do
, который итерации по аргументам. Не делайте ошибку, используя вместо этого for dir in $*; do
или for dir in $@; do
! Эти последние вызовы объединяют каждый элемент списка с первым символом IFS
(который по умолчанию содержит пространство, вкладку и новую строку в этом порядке), затем разбивает результирующую строку на любые IFS
символы, найденные внутри , затем расширяет каждый компонент результирующего списка в виде глоба. /dev/null
в качестве аргумента в grep
является мерой безопасности: она гарантирует, что у вас нет другого поведения между одно- аргумент и аргументы с несколькими аргументами (в качестве примера, grep
по умолчанию используется для печати имен файлов в выходном файле только при передаче нескольких аргументов) и гарантирует, что вы не можете grep
зависать, пытаясь читать из stdin, если он не передал никаких дополнительных имен файлов (f36] здесь не будет, но xargs
может). В случае, если это полезно для кого-то, работающего с Visual Studio 2013. Я обновил Visual Studio с 2010 по 2013, а затем начал видеть предупреждение о безопасности.
Используя Fiddler, я обнаружил, что VS 2013 продолжал отправлять запросы arterySignalR.
Я отключил это, установив следующее в web.config в appSettings
<add key="vs:EnableBrowserLink" value="false" />
, что привело к удалению предупреждения безопасности.
Я знаю, что это вызвано ' междоменным доступом к данным ', который я включил с помощью
jQuery.support.cors = true;
. В моем вызове Ajax мне пришлось указать jsonp
в качестве моего Тип данных, чтобы исправить проблему.
$.ajax({
url: "xxx",
dataType: "jsonp",
...
});
Это значительный риск для безопасности, который никогда не следует устанавливать для включения - существует большой класс атак в Интернете, которые полагаются на то, что для него установлено значение «Включить»; оставив его как можно быстрее, уменьшает доступность этого вектора атаки…
Столкнулся с этим сегодня и решил эту проблему, изменив настройки IE и обновив примечания к выпуску для моего приложения (на случай, если это кому-то нужно)
Перейдите в раздел «Интернет» -> «Безопасность» -> «Интернет» -> «Пользовательский уровень» -> Разное (перейдите к этому разделу) -> Доступ к источникам данных по доменам -> Установите для этого значение Включить
Я столкнулся с этой проблемой в своем HTA (на win 7) и исправил ее, проверив опции ниже:
IE (8) -> Tools -> Internet Options -> Advanced
Под заголовком Безопасность:
Warn about certificate address mismatch
Warn if changing between secure and not secure mode
После этого мой HTA больше не спрашивал меня с помощью всплывающего окна ..