df
метаданные файловой системы отчетов - т.е. что файловая система способна к хранению в данный момент. Важная вещь отметить состоит в том, что в некоторых файловых системах это должно не обязательно отразить свободное пространство (это - свободное место, хотя), так как фс может сделать предварительные выделения, когда это думает, что это - хорошая идея (например, XFS может сделать это, когда Вы начнете создавать большой файл - это выделит дополнительное место, чтобы гарантировать, что файл менее рассеивается и не проводит слишком много времени с выделениями, когда это должно будет записать фактические данные в диск). Такое пространство отмечено как доступное с некоторой задержкой. Информация также отражает факт, что некоторое пространство на диске (или мог бы быть), необходимый структурам файловой системы - это может вызвать любопытный эффект на некоторые файловые системы: создание отчетов о больше чем 100% располагает использование с интервалами.
du
даст Вам реальное использование диска с гранулярностью блоков файловой системы (в большинстве систем, не уверенных в тех, которые могут использовать один блок для данных нескольких файлов). Так как это имеет к stat()
каждый файл, принадлежащий главной иерархии каталогов (та du
дан на командной строке), это медленно, специально для случаев с маленькими файлами.
stat
даст Вам информацию о единственном файле (или каталог в этом отношении).
Следовательно, если Вы хотите знать:
сколько свободного пространства Вы имеете в файловой системе (приблизительно), использовать df
;
сколько данных Вы действительно имеете в файлах (не обязательно в единственной файловой системе), использовать du
- знайте, что это может легко стать медленным особенно в некоторых сетевых файловых системах;
сколько места запись для самого корневого каталога занимает, использовать stat /
.
Эти два примера демонстрируют различие:
$ echo _TMP_ | awk -v VAR='some "text"' '{ gsub(/_TMP_/, VAR) ; print }'
some "text"
$ echo _TMP_ | awk -v VAR='some "text"' '{ gsub(/_TMP_/, "VAR") ; print }'
VAR
Когда VAR
закрывается кавычки, awk
обработки это как переменная со значением some "text"
. Когда VAR
внутренние кавычки, awk рассматривает его как три символьных строки.
Еще: bash
имеет проблемы очистки. Рассмотрите:
$ VAR="rm important_file" ; $VAR
Вышеупомянутое сотрется important_file
. Таким образом, bash
похож на макроязык: это заменит переменную и затем попытается выполнить результат. awk
отличается. Рассмотрите:
$ echo _TMP_ | awk -v VAR='var); print $1' '{ gsub(/_TMP_/, VAR) ; print }'
var); print $1
awk
обработки VAR
как простой текст, не как потенциальные команды для выполнения.
Проблемы могут возникнуть, однако, если Вы позволяете bash
измените awk
сценарий. В моих примерах выше, awk
сценарии были всеми в одинарных кавычках. Это предотвращает bash
от питания с ними.
(Хорошо, извините я считал Ваш вопрос слишком быстро, таким образом, часть моего ответа немного не по существу, все еще оставляет его, как это - поскольку это может быть полезно для Вас или некоторых),
Существует несколько вещей рассмотреть здесь.
Отъезд переменной закрыл кавычки в оболочках POSIX (в контекстах списка, как в аргументах команде), нет awk
, split+glob оператор.
Если Вы делаете:
cmd foo=$var
Где $var
* *
.
Tha't, просящий, чтобы оболочка разделяла содержание $var
на основе значения $IFS
специальная переменная оболочки, по умолчанию на пробелах. Таким образом выше, который дает нам foo=*
и *
и выполните globbing на каждом из тех, который является, расширяются foo=*
ко всем именам файлов в текущем каталоге, которые запускаются с foo=
и *
ко всем нескрытым именам файлов.
Так, действительно, необходимо почти всегда заключать переменные оболочки в кавычки, являются ли они аргументами awk
или нет. Это также применяется к замене команды оболочки (`...`
и $(...)
) и окружите арифметическое расширение ($((...))
).
awk
Другая проблема - это awk
(не оболочка), разворачивает escape-последовательности обратной косой черты в присвоениях переменных как -v var=value
(и с GNU awk
4.2 или выше, если значение запускается с @/
и концы в /
, это рассматривают как regexp тип переменной).
Например, -v var='\n/\n/'
устанавливает содержание awk
var
переменная к <newline>/<newline>/
, нет \n/\n/
. Это также относится awk
переменные определяются как:
awk '...' var=value
Передать данные awk
без него подвергающийся тому расширению, можно использовать ENVIRON
или ARGV
массивы awk:
var=$value awk 'BEGIN {var=ENVIRON["var"]} ...'
(выше, это - присвоение переменной оболочки (к непеременной типа массив), таким образом, не может быть split+glob, который является одним из редких случаев, где можно опустить кавычки вокруг переменных),
или:
awk 'BEGIN {var=ARGV[1]; delete ARGV[1]} ...' "$value"
awk
переменныеЭто split+glob является только оболочкой (неправильная) функция. awk
язык является совершенно другим языком.
В awk
, переменные отнесены в a varname
, нет $varname
и кавычки используются для представления строк. Так "varname"
varname
строка, в то время как varname
относится к переменной.
Строго говоря заключение в кавычки переменных оболочки не санирует, оно не заключает переменные в кавычки, который использует split+glob оператор. На большинстве языков при помещении кавычек вокруг фиксированных строк, в оболочках, это наоборот: каждой вещью является строка, и кавычки используются для предотвращения некоторого специального поведения, и особенно переменные должны почти всегда заключаться в кавычки (плохое проектное решение такой имевший смысл в Оболочке Bourne в 70-х, но помеха в современных оболочках, zsh
будучи единственной оболочкой, которая частично зафиксировала это).
Оболочка или awk не оценят/интерпретируют код, сохраненный в их собственной переменной, если Вы не скажете им.
var='foo; rm -f var'
echo $var
# or
echo "$var"
Не заставит содержание переменной быть оцененным как код оболочки (хотя первый подвергнется разделению и globbing, который может иметь страшные последствия (например, с var='/*/*/*/*/../../../../*/*/*/*/../../../../*/*/*/*'
). Вам было бы нужно:
eval "echo $var"
# or
sh -c "echo $var"
чтобы это было оценено/интерпретировано как код оболочки.
awk
не имеет такого eval
функция. perl
/python
сделать.
Но остерегайтесь перекрестного загрязнения. У Вас могут быть данные переменной передачи оболочки (в переменных оболочки) как код для выполнения awk
:
awk '{print "'"$var"': " $0}'
было бы опасно в случае, если $var
переменная оболочки содержит, например:
var='test"; print "foo" > /etc/passwd; print "blah'
потому что оболочка затем выполнилась бы:
["awk", "{print \"test\"; print \"foo\" > /etc/passwd; print \"blah: \" $0}"]
Или наоборот:
awk '{system("echo foo: " $0)}' < file
где awk
выполнил бы оболочку как:
["sh", "-c", "echo foo: content-of-the-line"]
для каждой строки file
(и думайте что строка как ; rm -rf /
сделал бы).
Это не только между awk
и sh
. Необходимо быть осторожными каждый раз, когда переменные/неконтролируемые данные могут быть оценены как код другим интерпретатором. Примеры:
sed "s/$regexp/blah/g"
sed
язык ограничен, но он может все еще для нанесения вреда, как с regexp='//;w /etc/passwd; s/
'.
Или:
find . -exec sh -c "echo {}" \;
Теперь, для предотвращения тех проблем существует два общих подхода:
преобразуйте переменную от одного интерпретатора до другого. Это работает на оболочку-> awk, или найдите-> sh случай выше. Как изменение:
awk '{print "'"$var"': " $0}'
кому:
awk -v awk_var="$var" '{print awk_var ": " $0}'
И:
find . -exec sh -c "echo {}" \;
кому:
find . -exec sh -c 'echo "$1"' sh {} \;
но это не будет работать на оболочку-> sed, или awk-> случаи оболочки.
когда 1 не возможно, необходимо санировать переменные, чтобы или удалить или выйти из символов, которые могут быть проблемой. В,
awk '{system("echo foo: " $0)}'
необходимо преобразовать $0
к чему-то, что является чистой строкой насколько затронута оболочка. Одна опция состоит в том, чтобы снабдить префиксом каждый символ обратную косую черту, но это не будет работать на новую строку (не проблема здесь). Другой должен включить строку в одинарные кавычки и выйти из каждой одинарной кавычки.
awk 'function escape(s) {
gsub(/'\''/,"&\\\\&&",s)
return "'\''" s "'\''"
}
{system("echo foo: " escape($0))}'
$SOURCEIP
rm -fr /
. Если я передаю это awk через awk -v AWKVAREXAMPLE="$SOURCEIP"
и затем позже имейте awk, делают gsub как gsub(/^_TARGETSTRING_/, AWKVAREXAMPLE);
это в конечном счете "просочилось" бы в оболочку и уничтожило бы все?
– Mike B
06.02.2014, 10:16
awk
вызванный оболочка и передал это как код для него для интерпретации как в: awk '{system("echo " var)}'
(где var
;rm -rf /
), где awk
вызовы ["sh", "-c", "echo; rm -rf /"]
или awk '{print | "tr " v1 " " v2}'
где awk
передает вывод по каналу к ["sh", "-c", "tr content-of-v1 content-of-v2"]
. вещи
– Stéphane Chazelas
06.02.2014, 10:41
awk "{print \"$shell_variables\"}"
как там, содержание переменной оболочки интерпретируется как awk код.
– Stéphane Chazelas
06.02.2014, 10:43
Если вы передаете Awk переменной в систему , вам нужно указать ее в оболочке:
function quote(str, d, m, x, y, z) {
d = "\47"; m = split(str, x, d)
for (y in x) z = z d x[y] d (y < m ? "\\" d : "")
return z
}
Пример:
system(sprintf("ffmpeg -i %s outfile.m4a", quote(ARGV[1])))
VAR='blah; echo $1'
не проблема к оболочке ни один (если Вы не используетеeval
). Это не макроязык (кроме в некоторой степени wrt расширение псевдонима) – Stéphane Chazelas 06.02.2014, 11:28