On 25/08/2019 23.12, David Haller wrote:
Hello,
On Sun, 25 Aug 2019, Carlos E. R. wrote:
On 25/08/2019 21.29, David Haller wrote: [..] That's a very good idea! I often forget this "mc" feature.
*hehe*
I just googled "sanitize filename for FAT", and found "npm", but there is no package. There may be others.
And mostly, you'd find the "node package manager" ;(
Yes, I saw that.
You could also add recode/iconv into the mix to convert filenames, but that should be handled by the iocharset of the fat-mount. ISTR, that ':' and '\' are the only chars disallowed on FAT (modulo the charset and up-/downcase collisions handled by the kerneldriver). Anyway, you can basically do lots instead of that simple 'tr'.
I use ":" often, but never "/" or "\".
You can not use '/' on *nix, for the same reason you can not use '\' on DOS as it's the dir-seperator...
cer@Telcontar:~/tmp/david> touch "some\/file" touch: cannot touch 'some\/file': No such file or directory cer@Telcontar:~/tmp/david> touch "some/file" touch: cannot touch 'some/file': No such file or directory cer@Telcontar:~/tmp/david> Ok! :-)
Anyway: as I hinted, I'm aware of only that '\/' conflict, the ':' and the mentionend case and charset issues, and the latter two should be handled by the FAT fs-driver of the kernel and its mountoptions.
So I don't think you need to do anything more. And I think it's better to keep the case (FAT (at least FAT32) does preserve case IIRC, even though it folds case re. name-lookup etc.)...
$ dd of=minifat ... $ mkfs.vfat -F32 minifat # mount -o loop minifat /mnt/loop; mkdir /mnt/loop/t # echo A > /mnt/loop/t/A # echo b > /mnt/loop/t/b # sync; umount /mnt/loop # mount -o loop minifat /mnt/loop # mount |grep /mnt/ minifat on /mnt/loop type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro) # cat /mnt/loop/t/* cat /mnt/loop/t/* A b # echo a > /mnt/loop/t/a # cat /mnt/loop/t/* a b # ls -l /mnt/loop/t/ total 2 -rwxr-xr-x 1 root root 2 Aug 25 22:41 A -rwxr-xr-x 1 root root 2 Aug 25 22:41 b
So, FAT32/VFAT preserves the case, but folds it on access (or something to that effect).
Yes, FAT wit LFS (long filename support) allows writing low and upper case, but the automatically generated 8+3 name, which is the one actually used when it matters, I think it does not. Although you can force lower case on those by using a disk editor - at least I did that long ago in MsDOS.
So, folding case to all upper/lower in the copy action is IMO not a good idea, better preserve the case. If collisions occur, the fs-driver will tell cp and that should tell you... Mh. That's one thing I'd have to test but you could do better: error handling... Not sure how that works in the mc-menu extension...
*ARGH* It does not.
Some error handling of mine: + t t. D2 dd copy to other dir without o/p cache set %u while [ -n "$1" ] do if [ -e "%D/$1" ]; then play -q /usr/share/sounds/au/beep_kind_warning.au echo "Destination file $1 exists" else dd if="./$1" of="%D/$1" oflag=direct bs=16M status=progress fi shift done :-)
Ok, 'cp -i' works as so far as dropping you to a subshell letting 'cp -i' ask if you want to overwrite the target file or not... So use:
==== the "F" at the start of each second line is the shortcut ==== + ! t t F cp-rename to FAT-compatible filenames to=$(echo "%f" | tr ':\\' '__') cp -i "%d/%f" "%D/$to"
This one fails: cp: cannot stat '/data/hoard/files/test:\ 1': No such file or directory Correct, it is: /data/hoard/files/test: 1
+ t t F cp-rename to FAT-compatible filenames for i in %s ; do to=$(echo "$i" | tr ':\\' '__') cp -i "%d/$i" "%D/$to" done
But this one works perfectly. :-? I wrote a variant: + ! t t Fd dd-cp-rename to FAT-compatible filenames to=$(echo "%f" | tr ':\\' '__') #cp -i "%d/%f" "%D/$to" if [ -e "%D/$to" ]; then play -q /usr/share/sounds/au/beep_kind_warning.au echo "Destination file $to exists" else dd if="%d/%f" of="%D/$to" oflag=direct bs=16M status=progress fi (fails, obviously) + t t Fd dd-cp-rename to FAT-compatible filenames for i in %s ; do to=$(echo "$i" | tr ':\\' '__') #cp -i "%d/$i" "%D/$to" if [ -e "%D/$to" ]; then play -q /usr/share/sounds/au/beep_kind_warning.au echo "Destination file $to exists" else dd if="%d/$i" of="%D/$to" oflag=direct bs=16M status=progress fi done This variant writes at about 3.2 MB/s according to dd, and does not fill uselessly the system cache with data it is not going to reuse. I use that dd concoction for writing ISO images fast to the sticks; without "direct", the entire system becomes very slow. But I do not understand that gkrellm also shows reading going at double the write speed from that same stick. I mean, while the write operation is going on (with dd, not with cp). It seems to be is tumblerd :-? avidemux88:sink :-? Guessing, as the write is not cached, tumblerd has to read it again to do whatever it does :-? Yes, it is tumblerd. I killed it, and saw the reading stop. Write speed increases to 3.4 or 3.5. The silly thing is trying to index the video before writing is finished :-( 'cp' writes at what seems 3 MB/s, but often less than 1. I'd need something else to time it. One curious thing: the 'cp' process can not be killed, not even with -9.
====
else colliding target file will be overwritten as 'cp' is designed to do and 'a' will overwrite 'A'... Adding a 'test -e' for the dest into the scripts does not help, 'cp -i' is better as it drop you to the subshell.
I'm out of ideas for better error handling today, but ISTR, there are ways... A whole different idea would be an extfs for fat but you'd have to manually use that via F9 -> [Left/Right] -> FAT fs or somesuch or via 'mc foo/vfat://' ;)
But I'd just use the above with 'cp -i' and hope for few collisions ;)
Yep. -- Cheers / Saludos, Carlos E. R. (from 15.0 x86_64 at Telcontar)