Попытка заставить команду ADB в Linux (для копирования меток времени) работать с пробелами в именах

2

Используя Linux Mint 13, я пытался ADB скопировать файлы и каталоги на подключенный Android через USB. Необходимо сохранить временные метки.

(Я знаю, что в Unix хранится только измененное время).

Получил команду от Google, но не очень понимаю. Ссылка ниже. https://android.stackexchange.com/questions/35580/how-can-i-transfer-photos-to-my-android-jelly-bean-device-while-preserving-the-o

После adb нажмите "ОТ" "ANDROID_PHONE" Я использую команду ниже:

find . | while read file; do timestamp_stat=$(stat -c "%y" "$file"); timestamp=$(date +"%Y%m%d.%H%M%S" -d "$timestamp_stat"); echo "$timestamp: $file"; adb shell su -c "touch -t $timestamp \"/sdcard/ANDROID_PHONE\""; done

Я понимаю, что приведенной выше команде удается только использовать Touch для копирования меток времени для имен файлов и каталогов без пробелов в них. Получить сообщения об ошибках, например. Неизвестный идентификатор: R для тех, кто с пробелами.

Как я должен изменить код?

blue.grux
источник
Если вы используете file="$(line)" вместо read file, затем "$file" будет содержать любые начальные или конечные пробелы (или другие символы, кроме новых строк). Если у вас нет lineВы можете использовать эквивалент head -n 1, Но вы не должны иметь "$file" в adb вызов?
AFH
Посмотрел выше ... все еще не могу заставить его работать. Попробовал найти. -принт0 | во время чтения файла; Я думаю, я не знаю достаточно команд Linux, чтобы устранить эту проблему ..
blue.grux
Я думаю, что проблема может быть в двойном расширении: ваш хост расширяется один раз, а adb оболочка снова расширяется. Я до сих пор не понимаю, как adb Команда должна знать, какой файл touch команда должна действовать дальше; или есть что-то особенное в строке ANDROID_PHONE? В прошлом я монтировал Android как USB-накопитель, и я использовал обычную копию ( cp --preserve=all ) поддерживать отметки времени, не прибегая к adb, Теперь я использую приложение для управления файлами в Android для копирования по WiFi, и это также сохраняет их.
AFH
Привет AFH, спасибо за ответ. Проблема заключается в том, что временные метки для файлов сохраняются, а временные метки для каталогов - нет, что требует использования сценария / команды для «копирования» временных меток. Этот скрипт отлично работает для папок или имен файлов без пробелов. Я запускаю его из Linux с начала дерева папок, которое я хочу сравнить, и мне нужно только отредактировать часть "/ sdcard / Download / $ file \", чтобы отразить путь Android, с которым я хочу сравнить. Для установки Android в качестве USB-накопителя требуется USB Mass Storage, которого в более новых телефонах больше нет.
blue.grux
Если touch команда на андроиде должна быть touch -t $timestamp "/sdcard/ANDROID_PHONE/$file" тогда я вижу, что проблема двойного расширения, но без "$file" тогда я не могу понять, как это должно работать. Попутно я хотел бы отметить, что необычно изменять метки времени каталога, потому что они обновляются каждый раз, когда включаемый файл или подкаталог создается, удаляется или переименовывается.
AFH

Ответы:

1

Я могу объяснить часть этого:


find . используется для перечисления всех файлов и каталогов по текущему пути (это точка). Find не сказано ничего делать с результатами, но поведение по умолчанию в большинстве реализаций find заключается в том, чтобы выводить их в стандартный вывод.

Правильное кодирование использовало бы find /path/to/pictures -ls или же -print0, Последнее полезно, когда в имени есть нестандартные символы (например, пробелы).

Вывод предыдущей команды затем переходит к следующей части. Это делается через трубу ( | ) условное обозначение.


Следующая команда заключена в цикл while (выделено жирным шрифтом)

во время чтения файла; делать timestamp_stat = $ (stat -c "% y" "$ file"); отметка времени = $ (дата + "% Y% m% d.% H% M% S" -d "$ timestamp_stat"); echo "$ timestamp: $ file"; оболочка adb su -c "touch -t $ timestamp \" / sdcard / ANDROID_PHONE \ ""; сделанный

Это читает из файла (в нашем случае из stdin, который содержит выходные данные предыдущей команды. Результаты чтения хранятся в переменной с именем файл ,

(find - & gt; find output | -> input для цикла while)


Для каждого из этих результатов следующий набор команд выполняется в последовательности:

timestamp_stat=$(stat -c "%y" "$file");
timestamp=$(date +"%Y%m%d.%H%M%S" -d "$timestamp_stat"); 
echo "$timestamp: $file"; 
adb shell su -c "touch -t $timestamp \"/sdcard/ANDROID_PHONE\""; 

Переменная временная метка создана и заполнена результатами из stat -c
(stat - это утилита, отображающая информацию о файле, на который указывает файл. В этом случае файл, на который она указывает, хранится в $ file и помещается в кавычки, чтобы избежать проблем с пробелами.

Затем результаты заменяются той же информацией в другом формате.

Следующий результат - echo'd для std out. Это, вероятно, так что пользователь имеет некоторое представление о том, где находится скрипт.

Наконец, он делает что-то с abd, с которым у меня нет надежной информации. Я думаю, это поручает телефону Android коснуться файла. Касание файла обычно изменяет дату файла на текущее время. Однако в этом случае указывается время установки файла.

С сенсорной страницы:

-t      Change the access and modification times to the specified time
        instead of the current time of day.  The argument is of the form
         ``[[CC]YY]MMDDhhmm[.SS]'' where each pair of letters represents
         the following:


Переходя к решению:

К сожалению, не здесь, только намеки:

  • Изменить IFS
  • Или используйте -print0 (и возможно с xargs -0)
  • Используйте переместить вещь в поиск. Прямо сейчас find используется для поиска файлов, и результаты (включая пробелы) затем передаются в оболочку. Find может делать вещи самостоятельно, хотя. Нет пока readfile нужен. find /path/to/files -exec "something" {} \; может работать лучше и быстрее.
Hennes
источник
find <path> -exec <something> {} \; во многих случаях на самом деле медленнее. Это потому, что это начнется <something> на каждой итерации. Многие инструменты могут принимать произвольное количество входных файлов, в этом случае делать files=$(find <path> -print) && <something> $files быстрее, потому что он только начинается <something> один раз.
Gx1sptDTDa
Правда. Иногда вы можете обойти это, найдя \ +.
Hennes