2014-09-28 3 views
-1

В последнее время я действительно напортачил. У меня есть функция, которая будет поменять содержимое двух файлов:Где файлы tmp идут после того, как Bash заканчивается «локальной» переменной?

function swap()   
{ 
    local TMPFILE=tmp.$$ 
    mv "$1" "$TMPFILE" 
    mv "$2" "$1" 
    mv "$TMPFILE""$2" 
}    ^

Как вы можете видеть прямо рядом, где морковь указывает пространство отсутствует. В результате, выполнив следующую команду:

$ swap important.txt not-important.txt 

причина important.txt быть перезаписана не-important.txt и important.txt отправляются в пучину локального переменного Баша/файл

Are есть ли какие-либо варианты, не содержащие царапин на необработанных данных на диске?

$ grep -a -A1000 -B1000 "some text from important.txt" /dev/disk0 
+0

Ищите папку/tmp. Немного удачи, у вас ОС есть tmpfiles, например /tmp/tmp.1234, или из вашего сценария, я бы также посмотрел в текущем каталоге, вашем домашнем каталоге, вашем пути, для файлов с именем tmp. * – Pieter21

+0

Чтение ваш сценарий, я предполагал, что TMPFILE = tmp. $$ был некоторым bash, встроенным для tempfiles. Но, по-видимому, он просто помещает «tmp. » в TMPFILE. Поэтому временные файлы должны находиться в каталоге, в котором вы выполнили команду. Плохие новости здесь: если вы использовали swap() несколько раз в том же сеансе оболочки, имя временного файла всегда остается неизменным (и, следовательно, содержимое будет перезаписано в последующих вызовах) ... – misberner

+1

Для справки в будущем вам нужно 'TMPFILE = $ (mktemp) 'для генерации нового имени файла temp (в'/tmp/', по умолчанию), каждый раз вызывается' swap'.Кроме того, вы хотите только выполнить каждый 'mv', если предыдущий успешно, и (возможно) прервать программу, если какой-либо из них завершится неудачей:' mv '$ 1 "" $ TMPFILE "&& mv" $ 2 "" $ 1 "&& mv" $ TMPFILE "" $ 2 "|| {echo "swap failed"> & 2; выход 1; } '. – chepner

ответ

2

Вопрос не имеет смысла: Bash никогда не удаляет файлы автоматически, потому что это делается с локальной переменной. Переменная - это буквально только строка, содержащая имя файла - это не дескриптор файла каким-либо значимым образом. (Bash делает поддерживает реальные файлы, используя перенаправление, чтобы открывать файлы и отслеживать связанные FD или дескрипторы файлов, но ваш код здесь ничего не делает).


То есть:

mv "$1" "$TEMPFILE" 

переименовывает файл с именем уже хранится внутри TempFile переменной. Вы знаете, что это имя, потому что вы назначаете его в линии непосредственно перед:

local TMPFILE=tmp.$$ 

$$ является PID (или идентификатор процесса) текущей оболочки ... так mv "$1" "$TEMPFILE" также может быть записана в виде mv "$1" "tmp.$$". Содержимое файла не сохраняется в локальной переменной; там хранится только имя файла. Bash не удалит этот файл, но если вы снова вызовете функцию в том же каталоге из процесса с тем же идентификатором, он выберет одно и то же имя временного файла и, таким образом, перезапишет предыдущее содержимое файла.


Таким образом: В случае вашей функции swap, будет уходящие файлы вокруг на диске с именами вида tmp.###, где ### является PID в Баш экземпляра, запускаемого скрипта. Если ваше содержание все еще существует, они будут в файле с именем, соответствующим этой форме.

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