Немедленно войдите в последний каталог, который вы переименовали.

Последний подход с компиляцией in-VM кажется разумным и почти правильным. Однако я бы посоветовал сделать следующее :

  • ./configure --prefix=/usr/local Я не очень понимаю, почему вы решили установить префикс в каталоге /tmp. Он указывает на каталог, в который вы хотите установить приложение, я бы посоветовал придерживаться значения по умолчанию (не устанавливать его, или выбрать /usr/local в качестве префикса)
  • make. Здесь все в порядке.
  • Теперь перенесите каталог со скомпилированными двоичными файлами на вашего робота. Перед переносом было бы неплохо создать единый архив. Используйте tar cfz /tmp/openvpn_compiled.tgz
  • в системе вашего робота извлеките содержимое архива: tar xzf openvpn_compiled.tgz
  • войдите в каталог, который вы извлекли, и выдайте : make install

Теперь все должно работать отлично.

4
13.06.2017, 01:05
5 ответов

Когда вы переименовываете файл (типа каталога или другого), вы не изменяете его¹, поэтому время последнего изменения не меняется. Однако его статус изменениявремя (проверено -cminвместо -mmin) обновляется (по крайней мере, в Linux, однако POSIX не дает никаких гарантий на это) .

Изменяются каталоги, из которых вы перемещаете файл (при удалении/переименовании записи в нем) и в (при добавлении/переименовании записи в нем). Время их изменения состояния также будет изменено.

Таким образом, если вам нужна эвристика для поиска последней переименованной директории, можно найти файл с самым последним ctime, ctime которого отличается от mtime.

Для zsh:

ctime_is_mtime() {
  zmodload zsh/stat
  local -A stat
  zstat -H stat -- $REPLY &&
    ((stat[ctime] == stat[mtime]))
}

cd ./**/*(D/oc^+ctime_is_mtime[1])

Объяснение квалификаторов glob:

  • Dне пропускать скрытые файлы и каталоги
  • /рассматривать только файлы типа каталог
  • ocsort by ctime
  • ^not
  • +ctime_is_mtimeвызовите функцию для сравнения ctime с mtime.

Обратите внимание, что степень детализации по времени снижается до секунды только в тех файловых системах, которые поддерживают гранулярность до доли секунды.

Другие случаи, когда ctimeизменяется, но не mtime, включают любые изменения метаданных, кроме atimeпри доступе (например, chmod, chown, setfacl...), и использование touchдля установки произвольного времени модификации — еще один случай, когда ctimeи mtimeможет оказаться другим.


¹ технически, для каталога, когда он перемещается в другой каталог, вы изменяете его .. запись (которая теперь указывает на новый родительский каталог) для тех файловых систем, которые все еще хранят физические " ." и «..» записи в каталогах вместо их подделки на уровне ОС. Однако, AFAICT, системы по-прежнему не меняют mtime в этом случае.

2
27.01.2020, 20:46

Вы можете добавить это в свой файл .bashrc или .bash_aliases (или эквивалент, если ваша оболочка не bash):

mvcd () {
    mv -- "$1" "$2" &&
      cd -P -- "$2"
}

Затем перезапустите вашу оболочку, затем вы можно использовать такую ​​функцию:

mvcd foo bar

Предполагается, что $2не является существующим каталогом, иначе mvпереместит $1в его, а не на его (см. опцию -TGNU mvдля защиты от этого).

--отмечает конец опций. mv "$1" "$2"будет mv "$option_or_source" "$option_or_argument_to_first_option_or_destination".mv -- "$1" "$2"гарантирует, что $1и $2не рассматриваются как параметры, даже если их имя начинается с -поэтому он всегда обрабатывается как mv -- "$source" "$destination". Как правило, вы хотите использовать --везде, где команда получает произвольный аргумент.

-P(для физическогообхода каталога) предназначен для предотвращения специальной обработки, которую cdвстроенный в оболочки POSIX выполняет по умолчанию с .. компонентов пути, чтобы он обрабатывал содержимое $2так же, как mv. Без него в cdmv foo ../bar, cdможно было перейти в другой каталог barиз одного mv, переименованного в . ]fooкак.

Если вы установили $CDPATH(или это было в среде при запуске оболочки), вам также необходимо отключить его для этого вызова cd:

mvcd () {
    mv -- "$1" "$2" &&
      CDPATH= cd -P -- "$2"
}

Остаются некоторые дополнительные краеугольные проблемы: -(и в некоторых оболочках -2, +3) обрабатываются особым образом даже после --. Если вы хотите переименовать fooв -, используйте mvcd foo ./-вместоmvcd foo -.

7
27.01.2020, 20:46

Для завершения, чтобы попытаться ответить без каких-либо настроек в системе, вы можете сделать следующее:

TARGET="tgt_name"; mv src_name ${TARGET}; cd ${TARGET}

Очевидно, вы можете выбрать более короткое имя переменной, например A, но обратите внимание, что это может перезаписать переменные в вашем текущем сеансе. Если вас это беспокоит, подумайте о том, чтобы настроить среду для подоболочки:

env TARGET="tgt_name" bash -c 'mv src_name ${TARGET}; cd ${TARGET}'

Однако на данный момент я думаю, что мы более чем пересекли грань между удобством и сложностью, и было бы гораздо лучше настроить систему. с функцией mvcd из ответа Ли Райана.

1
27.01.2020, 20:46

В ksh93 и bash:

$ pwd
/tmp
$ mkdir test_dir
$ mv test_dir another_name
$ cd $_
$ pwd
/tmp/another_name

$_ заменяется на последний аргумент предыдущей команды.

В качестве функции оболочки:

mvcd () {
    mv -- "$1" "$2"
    cd -P -- "$_"
}

Но вы также можете использовать

mvcd () {
    mv -- "$1" "$2" &&
    cd -P -- "$2"
}

, так как это позаботится о том, чтобы не пытаться изменить каталог, если mv не удалось.

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

Команда -P с cd необходима для того, чтобы cd интерпретировала пути так же, как mv («физически» а не "логически"). Это позволяет избежать путаницы, когда новое местоположение указано с путем, который содержит .. и пересекает символические ссылки.

Если вы перемещаете, а не просто переименовываете каталог, нужно будет разобраться со случаем, когда перемещение не связано с переименованием каталога:

mv some_dir existing_dir

Это приведет к перемещению some_dir в существующий_каталог, поэтому нужно

cd existing_dir/some_dir

изменить рабочий каталог на перемещенный каталог впоследствии.

Об этом позаботится следующая модифицированная функция оболочки:

mvcd () {
    if [ -d "$2" ]; then
        mv -- "$1" "$2" &&
        cd -P -- "$2/$1"
    else
        mv -- "$1" "$2" &&
        cd -P -- "$2"
    fi
}

или "короче":

mvcd () {
    if [ -d "$2" ] && mv -- "$1" "$2"; then
        cd -P -- "$2/$1"
    elif mv -- "$1" "$2"; then
        cd -P -- "$2"
    fi
}

Невозможно объединить mv и cd в действительно атомарный операция. Сначала должен произойти mv, затем cd, как бы вы на это ни смотрели, даже если вы написали это на C. Делая одно за другим (проверяя статус выхода of mv) — правильный способ сделать это.

3
27.01.2020, 20:46

Вы можете изменить каталог перед вызовом mv. Это оставляет оболочку в замешательстве относительно текущего рабочего каталога. Это безвредно для приложений, пока источник и цель находятся в одной и той же файловой системе, но оставляет переменную PWD, встроенную функцию pwdи подсказку, показывающую старое местоположение, среди прочего. Чтобы обновить pwdи друзей в zsh и bash, вы можете использовать cd.; но в других оболочках это ничего не делает, и вместо этого вам нужно cd `pwd -P`; в обоих случаях это не сохраняет никакой информации о символических ссылках.

cd /some/where
mv "$PWD" /else/where
cd.                     # works in bash and zsh; use cd "`pwd`" in other shells

Вы можете опустить кавычки вокруг $PWD, если он не содержит специальных символов оболочки. Вы не можете использовать .в качестве источника mv, потому что сам .не может быть перемещен, для перемещения требуется «настоящая» запись в каталоге.

Преимущество этого решения состоит в том, что не требуется вводить какой-либо путь более одного раза, и оно устойчиво к mvдвум режимам работы, независимо от того, является ли его второй аргумент существующим каталогом или нет.

Вы можете запихнуть это в функцию, хотя основное преимущество этого подхода заключается в том, что он требует небольшого набора текста и не дает много пользы от функции. Если вы решите использовать функцию, я бы порекомендовал вместо этого один из подходов ниже.


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

mvcd () {
  mv "$@" && 
  if [ $# -eq 2 ] && [ ! -d "$2" ]; then
    cd "$2"
  else
    shift $(($#-2))
    cd "$2/${1##*/}"
  fi
}

Я использую более крупную и надежную функцию, которая устанавливает переменную movedв список целевых файлов.Его все еще можно обмануть, но вам придется больше работать. Я когда-либо удосужился написать его только для zsh, но его можно было бы адаптировать для bash и ksh.

function mv {
  emulate -LR zsh
  setopt extended_glob
  local i target=
  moved=("$@")
  while [[ $moved[1] == -* ]]; do
    case $moved[1] in
      -t?*) target=${moved[1]#*t};;
      --t*=*) target=${moved[1]#*=};;
      -t|--t*) target=$moved[2]; shift moved;;
      -S|--su) shift moved;;
      --) break;;
    esac
    shift moved
  done
  if [[ -z $target ]]; then
    target=$moved[-1]
    moved=($moved[1,-2])
  fi
  target=${target%%/##}
  if [[ -d $target ]]; then
    for ((i=1; i<=$#moved; i++)); do
      moved[$i]=$target/${${moved[i]%%/##}##*/}
    done
  else
    moved=($target)
  fi
  command mv "$@"
}

Затем, после команды mv, я могу делать такие вещи, как ls -ld $moved, cd $moved, xdg-open $moved(, это то, что я использую чаще всего )и т. д. Например,:

mvcd () {
  mv "$@" && cd -- $moved[-1]
}
0
27.01.2020, 20:46

Теги

Похожие вопросы