LINUX.ORG.RU

cp не копирует скрытые файлы с аргументом !

 , ,


0

0

Нужно скопировать /home/user со всем содержимым, но без /home/user/Desktop. Ввожу cp -prv /home/user/!(Desktop), Desktop не копирует, а вместе с ним не копирует всё, что начинается с точки в папке user. cp -prv /home/user/.!(Desktop) не копирует Desktop, но копирует только скрытые файлы. Что делать? Можно, конечно, использовать обе команды по очереди, но блин!..

Ответ на: комментарий от yars068

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

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от avgust23

А cp? Но ведь cp - один из столпов, на которых мы стоим, что за сраные ограничения, где гибкость?

Сразу вспомнил пасту с двача, единственное пришлось мат убрать:

 — Двач-медач, вот у меня почему-то раны вокруг рта…
 — Так ты ж ешь с ножа. Ложку попробуй.
 — Ложкотварь закукарекала. Ложкой мне неудобно.
 — Тогда йодом помажь, лалка.

 
 — Двач, а почему я суп так медленно ем? И мне очень неудобно.
 — Потому что ты ножом суп ешь? Ложкой ешь.
 — Ложкотвари не нужны! Бамп! Еще варианты? Бамп!
 — Ну отхлебни из тарелки тогда.
 — Сумасшедшие...

 
 — Двач, почему на меня в ресторане так странно поглядывают?
 — Потому что ты с ножа ешь!
 — Каждый раз одно и то же, что за дебильные анонимусы. А другого объяснения нет?
mamina_radost
()
Ответ на: комментарий от kaldeon

Есть «симптоматическое лечение». Оно не помогает выздороветь быстрее, и болезнь в итоге проходит сама, как и без лечения, но оно позволяет на этот период чувствовать себя намного лучше. Да хотя бы банально, если температура выше 40 поднялась, стоит выпить таблетку.

Если аналогию таки зачем-то продолжать, то наверное да, переименование ручками — это такое симптоматическое лечение.

P.S. Решение кривое и костыльное, но для спецолимпиады пойдёт. Кому действительно проблему решить, а не знание баша показать — давно всё скопировали с помощью rsync.

CrX ★★★★★
()
Ответ на: комментарий от kaldeon

В этом примере всратое всё! (=

IFS='
'

Но при этом ls без -1, шикарно!

grep -v Desktop

Что исключит не только ~/Desktop, но и любые файлы и директории, содержащие Desktop.

cp $(cat) /mnt/tvc15

Дёргать cat в subshell, чтобы получить вывод из пайпа? Сирёзна?! чем cp - /mnt/tcv15 не угодил?

mord0d ★★★★★
()
Ответ на: комментарий от CrX

Решение кривое и костыльное

Это не кривизна и костыль, а абстракция «одна линия = один файл». Баш осознанно выбрал эту абстракцию, потому что она позволяет перевести решение типичных проблем в область обработки текста: область, с которой человеку легко обращаться, где есть готовые инструменты.

Пример с rsync хорошо подошёл, не спорю, но об этих возможностях не всегда знаешь и они не всегда есть. Как открыть все картинки кроме одной в feh? У него нет опции exclude. Придётся использовать find и xargs, а это уже не так удобно.

И баш без того пронизан этой абстракцией. Она повсюду. Возьми любой системный скрипт на баше средних размеров, например mkinitcpio, где-нибудь список файлов будет представлен как список строк. В баше всё сделано, чтобы такой стиль работы был максимально удобным и выразительным.

Как и у всякой абстракции, у этой есть свои ограничения. Похожий пример: если мы всюду будем делать текстовые таблицы, то регулярные выражения перестанут работать. Но никто же не говорит, что foo.*png костыль для инвалидов.

kaldeon
()
Ответ на: комментарий от mord0d

Но при этом ls без -1, шикарно!

У тебя на аватарке freebsd изображён. Давай сходим в ман фряхи и посмотрим что там написано об этой опции:

Force output to be  one  entry  per line.  This is the default when output is not to a terminal.

https://man.freebsd.org/cgi/man.cgi?query=ls

Что исключит не только ~/Desktop, но и любые файлы и директории, содержащие Desktop.

Легко исправляется добавлением двух символов: ^ и $.

В принципе, вся мощь регулярных выражений в твоих руках. Ты можешь больше, чем с одной опцией exclude в rsync. Например, можно заигнорить любой файл с кириллицей: [а-яёА-ЯЁ].

Дёргать cat в subshell, чтобы получить вывод из пайпа? Сирёзна?!

Серьёзно. А что не так?

чем cp - /mnt/tcv15 не угодил?

Что такое «-»? Принцип юникса — «всё есть файл». /dev/stdin — это файл, а «-» — это какая-то херня или магия. /bin/cp копирует файлы. Мне разве нужно скопировать стандартный поток?

К тому же, эта команда не работает. Версия coreutils 9.7. cp /dev/stdin работает, но решает другую задачу.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 3)
Ответ на: комментарий от kaldeon

У тебя на аватарке freebsd изображён. Давай сходим в ман фряхи и посмотрим что там написано об этой опции:

Force output to be one entry per line. This is the default when output is not to a terminal.

Я знаю несколько способов запустить скрипт из crontab в pty. (=

Принцип юникса — «всё есть файл».

Нет, это принцип линукса.

/dev/stdin — это файл, а «-» — это какая-то херня или магия.

Это стандартный подход. Ты не можешь использовать /dev/stdin, он у каждого процесса разный и ссылается на разные дескрипторы. Чтобы не писать каждый раз код, который выявняет путь (которого физически может не быть, например там, где не используется procfs, то есть в любых UNIX-like кроме Linux) к нужному дескриптору, шелл предоставляет простой инструмент для его подстановки — -.

Дёргать cat в subshell, чтобы получить вывод из пайпа? Сирёзна?!

Серьёзно. А что не так?

А то, что тем самым ты дёргаешь не только сам cat, но и запускаешь для него шелл ($(...)${0:-$SHELL} -c "...") с передачей ему (экспортированного) окружения (то есть копирование памяти для дочернего процесса).

mord0d ★★★★★
()
Ответ на: комментарий от kaldeon

Я уверен, что весь юникс это нож. Единственная ложка это power shell, но линуксоидам он не зашёл.

Ужасная система. Простейшие задачи решаются через одно место, не полноценно и все делают вид, что это нормально.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от mord0d

Я знаю несколько способов запустить скрипт из crontab в pty. (=

Допустим. Но ведь ls | cat потеряет этот контекст, как он теряет его в обычном терминале.

Принцип юникса — «всё есть файл».

Нет, это принцип линукса.

Вот это поворот.

Ты не можешь использовать /dev/stdin, он у каждого процесса разный и ссылается на разные дескрипторы.

Он ссылается на один и тот же дескриптор: 0. Дескрипторы у каждого процесса свои.

Чтобы не писать каждый раз код, который выявняет путь (которого физически может не быть, например там, где не используется procfs, то есть в любых UNIX-like кроме Linux) к нужному дескриптору, шелл предоставляет простой инструмент для его подстановки — -.

Путь к дескриптору определяется не через procfs, а через открытие файла.

Кого там может не быть физически я не понял. /dev/stdin? С каких пор?

И шелл ничего не ставит на место «-». «-» передаётся как есть в /bin/cp, который в свою очередь ищет файл с именем «-» и, скорее всего, не может его найти. Шелл здесь вообще не при чём.

Ты сам пробовал запустить свою команду?

то есть копирование памяти для дочернего процесса

Речь идёт о переменных окружения.

Шелл не должен экономить память, его задача — организация, склеивание команд. Это в любом случае более дорогостоящая операция, чем делать всё самому через API операционной системы. Но зато это очень удобно.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 3)
Ответ на: комментарий от kaldeon

Я знаю несколько способов запустить скрипт из crontab в pty. (=

Допустим. Но ведь ls | cat потеряет этот контекст, как он теряет его в обычном терминале.

И с этим есть способы бороться если нужно. Но нужно ли? (=

Принцип юникса — «всё есть файл».

Нет, это принцип линукса.

Вот это поворот.

Оно есть и за пределами Linux, но только в Linux оно используется на полную. Во FreeBSD procfs есть, но по умолчанию не монтируется (и строго нужна паре-тройке сторонних приложений, таким как Java, например). И везде оно имеет свою структуру и формат.

Ты не можешь использовать /dev/stdin, он у каждого процесса разный и ссылается на разные дескрипторы.

Он ссылается на один и тот же дескриптор: 0. Дескрипторы у каждого процесса свои.

Не на один и тот же дескриптор, а на разные дескрипторы с одинаковым именем. Это не одно и то же.

Если ты линуксоид и/или у тебя есть под рукой линукс, загляни в procfs к разным процессам (путей не помню, так что сам разбирайся ☺) и поищи там дескрипторы с именем 0. А потом сравни их. ^_~

Кого там может не быть физически я не понял. /dev/stdin?

Дескриптора stdin (0) конкретного процесса. Это не одно и то же с /dev/stdin. В линуксе он скорее всего есть в procfs, во фряхе его 100% нет. (=

Шелл не должен экономить память, его задача — организация команд.

Твой "скрипт" тоже шелл написал? (%

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Но ведь ls | cat потеряет [запуск в pty]

И с этим есть способы бороться если нужно. Но нужно ли? (=

Я всего-лишь хотел сказать, что ls -1 вовсе не обязателен.

Принцип юникса — «всё есть файл». /dev/stdin — это файл …

Нет, это принцип линукса… . Оно есть и за пределами Linux, но только в Linux оно используется на полную. Во FreeBSD procfs есть …

Я говорил о том, что /dev/stdin — правильное имя стандартного потока, а «-» — какой-то костыль.

Ты не можешь использовать /dev/stdin, он у каждого процесса разный и ссылается на разные дескрипторы… . Не на один и тот же дескриптор, а на разные дескрипторы с одинаковым именем. Это не одно и то же.

Твоё пояснение верно, только никак не поясняет почему я не могу использовать /dev/stdin.

Дескриптора stdin (0) конкретного процесса [может не быть физически]. Это не одно и то же с /dev/stdin. В линуксе он скорее всего есть в procfs, во фряхе его 100% нет. (=

Как понять «может не быть физически»? Даже если его закрыть, ты можешь попробовать открыть его или /dev/stdin, только получишь ошибку вроде «bad file descriptor».

Но вот эта куча деталей здесь вообще к чему? Ты предложил команду |cp - /tmp/tvc15. В этой команде у /bin/cp всегда будет открыт stdin 0, даже если ты ранее его закрыл.

Кроме того, твоя команда не работает.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от kaldeon

Я всего-лишь хотел сказать, что ls -1 вовсе не обязателен.

Но является хорошим тоном делать вещи очевидными. (=

Я говорил о том, что /dev/stdin — правильное имя стандартного потока, а «-» — какой-то костыль.

Без ссылок на стандарты это не аргумент. Особенно по утверждению про костыль. (=

Твоё пояснение верно, только никак не поясняет почему я не могу использовать /dev/stdin.

Потому что это симлинк. В Linux он ведёт на /proc/self/fd/0, во FreeBSD он ведёт на /dev/fd/0. Да и чтение из дескриптора напрямую чаще всего ничего не даст при работе с пайпами.

Как понять «не существует»?

Вот так. В файловой иерархии его нет. Дескриптор открывается в памяти.
Это идёт в разрез с линуксовой идеологией «everything is a file». (=

Кроме того, твоя команда не работает.

Тогда ... | xargs cp /destination. (=

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Я всего-лишь хотел сказать, что ls -1 вовсе не обязателен.

Но является хорошим тоном делать вещи очевидными. (=

Когда то давно я отсортировал или отгрепал вывод ls а много позже заметил что обычно он выводит в несколько колонок но не удивился потому что очевидно же что если я передаю другой программе то мне несколько не нужно.

Для всех очевидны разные вещи.

sin_a ★★★★★
()
Ответ на: комментарий от kaldeon

Я всего-лишь хотел сказать, что ls -1 вовсе не обязателен.

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

ls | echo $(cat) 
cat: -: Ошибка ввода/вывода
ALiEN175
()
Ответ на: комментарий от mord0d

Я говорил о том, что /dev/stdin — правильное имя стандартного потока, а «-» — какой-то костыль.

Без ссылок на стандарты это не аргумент. Особенно по утверждению про костыль. (=

Мы обсуждаем не стандарты, а концепции. Такой вещи как «-» в юниксе нет. Это вещь, которую некоторые команды по своему желанию поддерживают. А /dev/stdin — это абстракция операционной системы.

Твоё пояснение верно, только никак не поясняет почему я не могу использовать /dev/stdin.

Потому что это симлинк.

Это до сих пор не объясняет почему я не могу использовать /dev/stdin.

И он не обязан быть симлинком. Это просто деталь реализации. В некоторых системах это не симлинк. И что с того? Как этот факт должен влиять на то, что нужно использовать «-» вместо /dev/stdin?

Да и чтение из дескриптора напрямую чаще всего ничего не даст при работе с пайпами.

Я абсолютно ничего не понимаю в том, что ты хочешь до нас донести. Команды по-умолчанию читают 0, в том числе в пайпах.

В файловой иерархии его нет. Дескриптор открывается в памяти.

Утверждение верное. Но оно не оправдывает сказанную ранее неразбериху про то, что кого-то там может не быть «физически». Как и не понятно, почему данное утверждение должно убедить нас не использовать /dev/stdin.

Тогда … | xargs cp /destination. (=

То есть ты больше не будешь настаивать на том, что надо использовать «-» вместо /dev/stdin?

Почему xargs хуже я говорил: cp не копирует скрытые файлы с аргументом ! (комментарий)

kaldeon
()
Ответ на: комментарий от sin_a

ls | grep это очевидно. А -1 это нечто очевидно лишнее.

Ты не совсем понял

Я совсем не понял. Твою логику. (=

Почему для тебя "очевидно лишнее" то, что делает команду более очевидной для всех?

Явное указание дефолта для избежания недопонимания, по твоему, плохо? Ты предлагаешь сэкономить три байта, чтобы кто-то потратил лишнюю минуту на прочтение мануала, потому что у него в интерактиве совершенно другой вывод.

И по поводу очевидности ls | grep я тоже с тобой не согласен. Вот сделал кто-то ls ~, увидел там ~/Desktop, добавил в grep -v, а потом «ой, а где мои фоточки из ~/Photo/My-photos-from-Desktop-2025-copy-1?!» Очевидно ли для него это было? Очевидно что нет.

Ты сам написал:

Для всех очевидны разные вещи.

Но тут же пытаешься проецировать свою субъективную точку зрения, полностью игнорируя возможные подводные камни и потенциально усложняя жизнь другим.

mord0d ★★★★★
()
Ответ на: комментарий от kaldeon

Это до сих пор не объясняет почему я не могу использовать /dev/stdin.

И он не обязан быть симлинком. Это просто деталь реализации. В некоторых системах это не симлинк. И что с того? Как этот факт должен влиять на то, что нужно использовать «-» вместо /dev/stdin?

Допустим у тебя одновременно работают две команды:

  • ... | command1
  • ... | command2

Внимание, вопрос! Какая из этих команд сейчас использует /dev/stdin? (%

Почему xargs хуже я говорил

Там ни слова о том, почему он хуже.

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Чтобы расколоть фисташку нужно думать как фисташка.

Если ты поглядишь глазами программиста то увидишь что в случае конвейера несколько колонок не нужны. И это совершенно очевидно.

И в случае -1 это я зависну пытаясь понять что это такое и зачем это здесь.

Очевидно ли для него это было?

А как здесь поможет -1 ?

sin_a ★★★★★
()
Ответ на: комментарий от mord0d

Внимание, вопрос! Какая из этих команд сейчас использует /dev/stdin? (%

Он у каждой команды свой. Повторю вопрос: почему я должен использовать cp - dst, но не могу использовать cp /dev/stdin dst?

Там ни слова о том, почему [xargs] хуже.

Мне придётся подчеркнуть слова.

Вариант с IFS лучше [xargs], потому что позволяет решить проблему на уровне языка. Это проявляется, например, в том, что я могу более естественно написать cp src dst, а не cp -t dst src. В openbsd, например, нет опции -t.

Нужно дополнительно объяснить почему решение «на уровне языка» лучше обходных путей?

Нужно дополнительно объяснить, что cp src dst предпочтительнее cp -t dst src?

Нужно дополнительно объяснить, что cp $(cat) /tmp короче и прямолинейнее выглядит, чем xargs -d\n -i{} cp {} /tmp?

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от sin_a

Ему пофиг на эту логику: «в случае конвейера несколько колонок не нужны».

Он цепляется за эти слова:

И это совершенно очевидно.

Для всех очевидны разные вещи.

То есть абсолютно что угодно может быть на абсолютно неизвестном уровне очевидности для абсолютно любого человека. Контекст, иерархия сложности не волнуют.

Чисто философский наезд.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от mord0d

И по поводу очевидности ls | grep я тоже с тобой не согласен. Вот сделал кто-то ls ~, увидел там ~/Desktop, добавил в grep -v, а потом «ой, а где мои фоточки из ~/Photo/My-photos-from-Desktop-2025-copy-1?!» Очевидно ли для него это было? Очевидно что нет.

Если пользователь не знает, что grep матчит часть строки, то ему следует поближе познакомиться с шеллом. Это основной мультитул.

Не вина других людей, что они используют простой и распространённый (даже традиционный) инструмент, причём без каких-либо необычных расширений.

kaldeon
()
Ответ на: комментарий от kaldeon

Если пользователь не знает, что grep матчит часть строки, то ему следует поближе познакомиться с шеллом.

«Если пользователь не знает как завязывать шнурки, ему следует сходить на курсы вождения.»

Из всего нашего диалога я понял что у тебя шизофрения. Дальнейший диалог невозможен. (=

mord0d ★★★★★
()
Ответ на: комментарий от avgust23

а чем просто два аргумента как источники не угодили?

cp -r /home/user/!(Desktop) /home/user/.[a-zA-Z0-9]* TARGET

и да, для большинства случаев первый аргумент можно переписать как просто [A-CE-Za-z0-9]*

mumpster ★★★★★
()
Ответ на: комментарий от kaldeon

ииии?

зачем на м мнение какого-то неизвестного китайца?

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

mumpster ★★★★★
()
Ответ на: комментарий от avgust23

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

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

например, когда мне бывает надо слить всю ФС целиком, я делаю также - исключаю l* (lost+found) по [A-Za-km-z] и перечисляю остальные папки на l* если они там есть - так надёжнее и проще как не странно

mumpster ★★★★★
()
Ответ на: комментарий от mumpster

Это нужно каждый раз смотреть какие там есть папки. Например, если там есть lost, нужно его обязательно указать. Надёжнее перечислить всё, а lost+found убрать grep’ом. Это буквально задача grep’а. Список файлов может прилететь из любого места в виде обычного текста, не обязательно из текущей файловой системы — это буквальный принцип юникса.

нет никакой проблемы с точкой, это просто спецслучай

Спецслучай плох тем, что он усложняет все проблемы в два раза и не даёт очевидных ответов. Взять ту же * (символ «звёздочка») — он должен в себя включать скрытые файлы? А другие программы (например, файловый менеджер) должны копировать чужое поведение или искать ответ заново? Например, обычный файловый менеджер может скрывать файлы, а файловый менеджер для админов будет их показывать. И даже знающий админ в один день запутается из-за разного поведения. Потому что это противоречие в принципах. То, что справедливо для одного файла, должно быть справедливым для всех файлов всегда и без исключения. Если ls не показывает bashrc, то bashrc — это не файл.

Конфиги — не помощник. Те, кто привыкли всё конфигурировать, теряют способность комфортно работать на чужих машинах.

В Plan 9 * («звёздочка») и ls показывают все файлы. Если конкретный пользователь лично для себя захочет исключить дотфайлы, он может сделать grep -v ^\. — простейшая юникс-вейная команда. Но отсутствие спецслучая на уровне системы упрощает ему жизнь, не заставляет искать научные ответы на философские вопросы на пустом месте, предлагать PostgreSQL вместо дерева.

в венде у тя с этим случаями даже системы нет окромя флага в ФС

Точка — это хороший маркер. Её легко увидеть глазами и сразу учесть в работе, а метаданных много и не видно сразу.

Проблема в том, что точка в начале ну никак не говорит о том, что файл должен быть скрыт. Если ты напишешь “.bashrc” на листке бумаги или в текстовом редакторе, то чернила не станут прозрачными. Вот и разработчик какого-нибудь условного API менеджера паролей, когда будет делать getfiles(), не учтёт, что если его метод вернёт “.pornhub.com”, то конечный пользователь его не увидит. Это, кстати, очередной пример, когда плохая типографика рождает плохие интерфейсы.

Если случай особый, то он должен иметь особый интерфейс.

Я не знаю деталей API винды и не могу всецело оценить его. Но там по-любому есть какой-то фильтр и шансов больше, что хотя бы грамотный разработчик учтёт его в дизайне своего API менеджера паролей, что особый случай сохранится как особый, что “.pornhub.com” не высветится в меню поиска.

kaldeon
()