Delete file with odd character in filename - linux

I cannot delete a file that is copy of a backup of a backup... I don't remember all the filesystem character set it has passed by.
Anyway, today here's the file:
nas# ls -al
ls: cannot access Sécurité: No such file or directory
total 32
drwx------ 4 sambacam sambacam 20480 Jun 5 01:38 .
drwxr-xr-x 3 sambacam sambacam 12288 Jun 5 01:38 ..
d????????? ? ? ? ? ? S??curit??
nas# cd S*
cd: 13: can't cd to Sécurité
nas# rm "Sécurité"
rm: cannot remove `S\303\251curit\303\251': No such file or directory
nas# rm S*
rm: cannot remove `S\303\251curit\303\251': No such file or directory
nas#
I even tried to code in Python without success:
nas# python
Python 2.5.2 (r252:60911, Jan 24 2010, 20:48:41)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> d=os.listdir('.')
>>> d
['S\xc3\xa9curit\xc3\xa9']
>>> d[0]
'S\xc3\xa9curit\xc3\xa9'
>>> os.remove(d[0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: 'S\xc3\xa9curit\xc3\xa9'
>>>
Any idea?
I already ran fsck to check for inconsistencies.

I think you've got worse problems:
d????????? ? ? ? ? ? S??curit??
This means that ls(1) was unable to find permissions, link count, owner, group, size, or mtime of your file. All it has is a filename.
This could happen if the directory structure points to a file, but the inode for that file has gone missing. I would hope a fsck would find it and clean up the directory entry, but if that hasn't happened, you might not be able to ever empty this directory on this filesystem. (You could move it wherever you wanted, even into the /lost+found, and not be bothered by it again...)
Perhaps the debugfs(8) tool would be useful in learning more?

Have you tried with the inode number trick? Do:
ls -ilb
The first number in that list is the inode number. The -b switch makes ls not try to print non-printable chars. Once you have the inode number from the file, try:
find . -inum the_number_from_above -exec rm -i {} \;
(BTW: that's UTF-8 encoding.)
I'm not sure it will work though. The fact that ls isn't finding the file's metadata (timetamps and permission bits) looks like filesystem corruption.

Related

python3 pathlib mkdir Permission denied

This code raised exception when I tried to create a sub dir ./test/123 under ./test/. And after examine the permission, I found that dir ./test created by this code has d-w----r--, which is strange...If I mkdir in the terminal, that dir will have drwxr-xr-x permission.
from pathlib import Path
if __name__ == '__main__':
p1 = Path('./test')
p1.mkdir(644, parents=True, exist_ok=True)
p2 = Path('./test/123')
p2.mkdir(644, parents=True, exist_ok=True)
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/pathlib.py", line 1267, in mkdir
if not exist_ok or not self.is_dir():
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/pathlib.py", line 1358, in is_dir
return S_ISDIR(self.stat().st_mode)
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/pathlib.py", line 1168, in stat
return self._accessor.stat(self)
PermissionError: [Errno 13] Permission denied: 'test/123'
Pathlib expects an octal integer instead of decimal. You can denote octal by preficing your mode bits 644 with 0o, i.e. 0o644. 644 decimal translates to 1204 in octal which imposes permissions you are seeing there.
Also, to traverse a directory structure you require both read and execute permissions on it, so I would recommend using 0o755 instead of 0o644.
The Unix command line chmod assumes octal whereas your python pathlib library does not. Hope this helps.

Run script on specific file in all subdirs

I've written a script (foo) which makes a simple sed replacement on text in the input file. I have a directory (a) containing a large number of subdirectories (a/b1, a/b2 etc) which all have the same subdirs (c, etc) and contain a file with the same name (d). So the rough structure is:
a/
-b1/
--c/
---d
-b2/
--c/
---d
-b3/
--c/
---d
I want to run my script on every file (d) in the tree. Unfortunately the following doesn't work:
sudo sh foo a/*/c/d
how do I use wildcards in a bash command like this? Do I have to use find with specific max and mindepth, or is there a more elegant solution?
The wildcard expansion in your example should work, and no find should be needed. I assume a b and c are just some generic file names to simplify the question. Do any of your folders/files contain spaces?
If you do:
ls -l a/*/d/c
are you getting the files you need listed? If so, then it is how you handle the $* in your script file. Mind sharing it with us?
As you can see, wildcard expansion works
$ ls -l a/*/c/d
-rw-r--r-- 1 user wheel 0 15 Apr 08:05 a/b1/c/d
-rw-r--r-- 1 user wheel 0 15 Apr 08:05 a/b2/c/d
-rw-r--r-- 1 user wheel 0 15 Apr 08:05 a/b3/c/d

why does tar -cf ${PWD}.bz2 not produce any output?

I ran the following command. tar -jcvf ${PWD}.bz2 a b c d. I expected a bz2 folder as the output. But the command did not output anything. what am i missing ?
your command syntax is correct, so if you have permissions for reading a,b,c,d file (or directory???) and write to ./.. directory (one level up), file should be created.
example command output (a,b,d - files, c - directory with 2 files)
a
b
c/
c/file2
c/file1
d
at the end just type:
stat ${PWD}.bz2
Regards,
When you want a output file in a bz2 dir, use ${PWD}/bz2/outputfile

Permission denied in ubuntu

I have the following Lua code:
local f = io.popen("/home/mohammad/LUA", "r")
if f then
print(f:read("*a"))
else
print("failed to read")
end
When I execute it in Ubuntu I get an error:
mohammad#ubuntu:~$ lua LUA/project.lua
sh: 1: /home/mohammad/LUA: Permission denied
This is the file permission:
-rwxrwxrwx 1 mohammad mohammad 1185 Feb 3 01:56 LUA/project.lua*
What is the problem? How can I solve it?
You are doing
lua LUA/project.lua
If project.lua is in /home/mohammad/LUA then with
io.popen("/home/mohammad/LUA", "r")
you are attempting to popen (pipe-open) the folder. But popen docs in Lua ref manual say
Starts program prog in a separated process and returns a file handle
that you can use to read data from this program
A folder is not a process so this won't work.
If you meant to use io.open, the call will succeed if folder exists, and the return will be non-nil on Linux (some differences between Linux and Windows in Why is this lua script unable to open a Windows subdirectory?).

Linux: Unzip an archive containing files with the same name

I was sent a zip file containing 40 files with the same name.
I wanted to extract each of these files to a seperate folder OR extract each file with a different name (file1, file2, etc).
Is there a way to do this automatically with standard linux tools? A check of man unzip revealed nothing that could help me. zipsplit also does not seem to allow an arbitrary splitting of zip files (I was trying to split the zip into 40 archives, each containing one file).
At the moment I am (r)enaming my files individually. This is not so much of a problem with a 40 file archive, but is obviously unscalable.
Anyone have a nice, simple way of doing this? More curious than anything else.
Thanks.
Assuming that no such tool currently exists, then it should be quite easy to write one in python. Python has a zipfile module that should be sufficient.
Something like this (maybe, untested):
#!/usr/bin/env python
import os
import sys
import zipfile
count = 0
z = zipfile.ZipFile(sys.argv[1],"r")
for info in z.infolist():
directory = str(count)
os.makedirs(directory)
z.extract(info,directory)
count += 1
z.close()
I know this is a couple years old, but the answers above did not solve my particular problem here so I thought I should go ahead and post a solution that worked for me.
Without scripting, you can just use command line input to interact with the unzip tools text interface. That is, when you type this at the command line:
unzip file.zip
and it contains files of the same name, it will prompt you with:
replace sameName.txt? [y]es, [n]o, [A]ll, [N]one, [r]ename:
If you wanted to do this by hand, you would type "r", and then at the next prompt:
new name:
you would just type the new file name.
To automate this, simply create a text file with the responses to these prompts and use it as the input to unzip, as follows.
r
sameName_1.txt
r
sameName_2.txt
...
That is generated pretty easily using your favorite scripting language. Save it as unzip_input.txt and then use it as input to unzip like this:
unzip < unzip_input.txt
For me, this was less of a headache than trying to get the Perl or Python extraction modules working the way I needed. Hope this helps someone...
here is a linux script version
in this case the 834733991_T_ONTIME.csv is the name of the file that is the same inside every zip file, and the .csv after "$count" simply has to be swapped with the file type you want
#!/bin/bash
count=0
for a in *.zip
do
unzip -q "$a"
mv 834733991_T_ONTIME.csv "$count".csv
count=$(($count+1))
done`
This thread is old but there is still room for improvement. Personally I prefer the following one-liner in bash
unzipd ()
{
unzip -d "${1%.*}" "$1"
}
Nice, clean, and simple way to remove the extension and use the
Using unzip -B file.zip did the trick for me. It creates a backup file suffixed with ~<number> in case the file already exists.
For example:
$ rm *.xml
$ unzip -B bogus.zip
Archive: bogus.zip
inflating: foo.xml
inflating: foo.xml
inflating: foo.xml
inflating: foo.xml
inflating: foo.xml
$ ls -l
-rw-rw-r-- 1 user user 1161 Dec 20 20:03 bogus.zip
-rw-rw-r-- 1 user user 1501 Dec 16 14:34 foo.xml
-rw-rw-r-- 1 user user 1520 Dec 16 14:45 foo.xml~
-rw-rw-r-- 1 user user 1501 Dec 16 14:47 foo.xml~1
-rw-rw-r-- 1 user user 1520 Dec 16 14:53 foo.xml~2
-rw-rw-r-- 1 user user 1520 Dec 16 14:54 foo.xml~3
Note: the -B option does not show up in unzip --help, but is mentioned in the man pages: https://manpages.org/unzip#options

Resources