Is quoting filenames enough security for running `xargs sudo rm -rf`?
Clash Royale CLAN TAG#URR8PPP
up vote
10
down vote
favorite
I wrote a script that deletes all except the last two files in a folder:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder
| head -n -2
| xargs printf -- "'/path/to/some/folder/%s'n"
| xargs sudo rm -rf
This script will be executed as a cron job every day.
The reasoning is as follows:
Obtain a list of all files using
ls -1
(so that I get one file per line);Remove the last two from the list using
head -n -2
;Since
ls
prints relative paths, use thexargs printf
thing to prepend the folder path and make it an absolute path;Send them to
sudo rm -rf
usingxargs
.
Everyone has access to this folder, so anyone can create and delete any files in this folder.
The problem is: sudo rm -rf
is scary. xargs sudo rm -rf
is incredibly scary.
I want to be sure that no one can damage other folders/systems by creating clever files to be deleted (either accidentally or on purpose). I don't know, something clever like:
file with / spaces.txt
which could result in a super scary sudo rm -rf /
.
EDIT: My mistake, file names cannot contain /
, so this specific problem wouldn't happen, but the question about whether or not there are other risks still stands.
This is why I am using --quoting-style=shell-always
, this should prevent any tricks with files with spaces. But now I am wondering if someone could be extra clever with spaces and quotes in the filename, perhaps.
Is my script safe?
Note: I need sudo
because I am acessing the folder remotely (from a mapped network drive using mount
), and I couldn't get it to work without sudo.
command-line bash scripts security rm
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
 |Â
show 3 more comments
up vote
10
down vote
favorite
I wrote a script that deletes all except the last two files in a folder:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder
| head -n -2
| xargs printf -- "'/path/to/some/folder/%s'n"
| xargs sudo rm -rf
This script will be executed as a cron job every day.
The reasoning is as follows:
Obtain a list of all files using
ls -1
(so that I get one file per line);Remove the last two from the list using
head -n -2
;Since
ls
prints relative paths, use thexargs printf
thing to prepend the folder path and make it an absolute path;Send them to
sudo rm -rf
usingxargs
.
Everyone has access to this folder, so anyone can create and delete any files in this folder.
The problem is: sudo rm -rf
is scary. xargs sudo rm -rf
is incredibly scary.
I want to be sure that no one can damage other folders/systems by creating clever files to be deleted (either accidentally or on purpose). I don't know, something clever like:
file with / spaces.txt
which could result in a super scary sudo rm -rf /
.
EDIT: My mistake, file names cannot contain /
, so this specific problem wouldn't happen, but the question about whether or not there are other risks still stands.
This is why I am using --quoting-style=shell-always
, this should prevent any tricks with files with spaces. But now I am wondering if someone could be extra clever with spaces and quotes in the filename, perhaps.
Is my script safe?
Note: I need sudo
because I am acessing the folder remotely (from a mapped network drive using mount
), and I couldn't get it to work without sudo.
command-line bash scripts security rm
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3
Have you considered doing something likeprintf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?
– steeldriver
Sep 4 at 17:45
Can a file with the character/
in the name be created I am trying to achieve this back here
– George Udosen
Sep 4 at 17:52
3
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
5
Simply because you're parsingls
output this is already a poorly written command, even with quoting.ls
also uses locale for sorting order, I think, so I don't see what's the purpose ofhead
in removing last 2 ( unless you're trying to get rid of.
and..
which iirc aren't allowed as arguments torm
anyway. Just usefind /path/to/folder -type f delete
. And nosudo
if you run from cron - cron is already at root level
– Sergiy Kolodyazhnyy
Sep 4 at 19:35
 |Â
show 3 more comments
up vote
10
down vote
favorite
up vote
10
down vote
favorite
I wrote a script that deletes all except the last two files in a folder:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder
| head -n -2
| xargs printf -- "'/path/to/some/folder/%s'n"
| xargs sudo rm -rf
This script will be executed as a cron job every day.
The reasoning is as follows:
Obtain a list of all files using
ls -1
(so that I get one file per line);Remove the last two from the list using
head -n -2
;Since
ls
prints relative paths, use thexargs printf
thing to prepend the folder path and make it an absolute path;Send them to
sudo rm -rf
usingxargs
.
Everyone has access to this folder, so anyone can create and delete any files in this folder.
The problem is: sudo rm -rf
is scary. xargs sudo rm -rf
is incredibly scary.
I want to be sure that no one can damage other folders/systems by creating clever files to be deleted (either accidentally or on purpose). I don't know, something clever like:
file with / spaces.txt
which could result in a super scary sudo rm -rf /
.
EDIT: My mistake, file names cannot contain /
, so this specific problem wouldn't happen, but the question about whether or not there are other risks still stands.
This is why I am using --quoting-style=shell-always
, this should prevent any tricks with files with spaces. But now I am wondering if someone could be extra clever with spaces and quotes in the filename, perhaps.
Is my script safe?
Note: I need sudo
because I am acessing the folder remotely (from a mapped network drive using mount
), and I couldn't get it to work without sudo.
command-line bash scripts security rm
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I wrote a script that deletes all except the last two files in a folder:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder
| head -n -2
| xargs printf -- "'/path/to/some/folder/%s'n"
| xargs sudo rm -rf
This script will be executed as a cron job every day.
The reasoning is as follows:
Obtain a list of all files using
ls -1
(so that I get one file per line);Remove the last two from the list using
head -n -2
;Since
ls
prints relative paths, use thexargs printf
thing to prepend the folder path and make it an absolute path;Send them to
sudo rm -rf
usingxargs
.
Everyone has access to this folder, so anyone can create and delete any files in this folder.
The problem is: sudo rm -rf
is scary. xargs sudo rm -rf
is incredibly scary.
I want to be sure that no one can damage other folders/systems by creating clever files to be deleted (either accidentally or on purpose). I don't know, something clever like:
file with / spaces.txt
which could result in a super scary sudo rm -rf /
.
EDIT: My mistake, file names cannot contain /
, so this specific problem wouldn't happen, but the question about whether or not there are other risks still stands.
This is why I am using --quoting-style=shell-always
, this should prevent any tricks with files with spaces. But now I am wondering if someone could be extra clever with spaces and quotes in the filename, perhaps.
Is my script safe?
Note: I need sudo
because I am acessing the folder remotely (from a mapped network drive using mount
), and I couldn't get it to work without sudo.
command-line bash scripts security rm
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited Sep 5 at 22:31


heemayl
64k8127203
64k8127203
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked Sep 4 at 17:24
Pedro A
1566
1566
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Pedro A is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3
Have you considered doing something likeprintf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?
– steeldriver
Sep 4 at 17:45
Can a file with the character/
in the name be created I am trying to achieve this back here
– George Udosen
Sep 4 at 17:52
3
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
5
Simply because you're parsingls
output this is already a poorly written command, even with quoting.ls
also uses locale for sorting order, I think, so I don't see what's the purpose ofhead
in removing last 2 ( unless you're trying to get rid of.
and..
which iirc aren't allowed as arguments torm
anyway. Just usefind /path/to/folder -type f delete
. And nosudo
if you run from cron - cron is already at root level
– Sergiy Kolodyazhnyy
Sep 4 at 19:35
 |Â
show 3 more comments
3
Have you considered doing something likeprintf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?
– steeldriver
Sep 4 at 17:45
Can a file with the character/
in the name be created I am trying to achieve this back here
– George Udosen
Sep 4 at 17:52
3
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
5
Simply because you're parsingls
output this is already a poorly written command, even with quoting.ls
also uses locale for sorting order, I think, so I don't see what's the purpose ofhead
in removing last 2 ( unless you're trying to get rid of.
and..
which iirc aren't allowed as arguments torm
anyway. Just usefind /path/to/folder -type f delete
. And nosudo
if you run from cron - cron is already at root level
– Sergiy Kolodyazhnyy
Sep 4 at 19:35
3
3
Have you considered doing something like
printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?– steeldriver
Sep 4 at 17:45
Have you considered doing something like
printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?– steeldriver
Sep 4 at 17:45
Can a file with the character
/
in the name be created I am trying to achieve this back here– George Udosen
Sep 4 at 17:52
Can a file with the character
/
in the name be created I am trying to achieve this back here– George Udosen
Sep 4 at 17:52
3
3
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
5
5
Simply because you're parsing
ls
output this is already a poorly written command, even with quoting. ls
also uses locale for sorting order, I think, so I don't see what's the purpose of head
in removing last 2 ( unless you're trying to get rid of .
and ..
which iirc aren't allowed as arguments to rm
anyway. Just use find /path/to/folder -type f delete
. And no sudo
if you run from cron - cron is already at root level– Sergiy Kolodyazhnyy
Sep 4 at 19:35
Simply because you're parsing
ls
output this is already a poorly written command, even with quoting. ls
also uses locale for sorting order, I think, so I don't see what's the purpose of head
in removing last 2 ( unless you're trying to get rid of .
and ..
which iirc aren't allowed as arguments to rm
anyway. Just use find /path/to/folder -type f delete
. And no sudo
if you run from cron - cron is already at root level– Sergiy Kolodyazhnyy
Sep 4 at 19:35
 |Â
show 3 more comments
2 Answers
2
active
oldest
votes
up vote
10
down vote
accepted
In Linux, any character is a valid filename constituting character except:
(ASCII NUL): as used for string termination in C
/
(forward slash): as used for path separation
So, your approach will definitely not work in many cases as you can imagine e.g. does it handle a newline (n
) in filename? (Hint: No).
Few notes:
- Don't parse
ls
; use dedicated tools (there is at least one for most use cases) - When dealing with filenames, try to leverage the NUL separated output provided by almost all GNU tools that work with such data
- Take care when piping, make sure both programs can understand NUL separations
- Whenever you're invoking
xargs
, see if you can get away withfind ... -exec
; in most cases, you will be fine with justfind
alone
I think these will get you going for now. steeldriver already provided the NUL separated idea in the comment (printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use this as a starting point.
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look intofind
as well, thanks for the suggestion.
– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases yourls
parsing approach would fail e.g. did you take into account a newline in filename?
– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what doeshead -z
do? It sounds ridiculous but I don't haveman
norinfo
in my CoreOS container linux... Couldn't find in the internet either. I gethead: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNUhead
(comes with GNUcoreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
– heemayl
Sep 5 at 13:54
 |Â
show 3 more comments
up vote
3
down vote
xargs
does support some quoting: with single quotes, double quotes or backslash which allows it to accept arbitrary arguments¹, but with a syntax that is different from the Bourne-like shells' quoting syntax.
The GNU implementation of ls
as found on Ubuntu doesn't have any quoting mode that is compatible with the xargs
input format.
Its ls --quoting-style=shell-always
is compatible with ksh93, bash and zsh shells quoting syntax, but only when the output of ls
is interpreted by the shell in the same locale as ls
was when it output it. Also, some locales, like those using BIG5, BIG5-HKSCS, GBK or GB18030 should be avoided.
So with those shells, you can actually do:
typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s' "$files[@]:0:3") ...
But that has little advantage over:
files=(*(N)) # zsh
files=(~(N)*) # ksh93
shopt -s nullglob; files=(*) # bash
The only case where it becomes useful is when you want to use the -t
option of ls
to sort the files by mtime/atime/ctime or -S
/-V
. But even then, you might as well use zsh
's:
files=(*(Nom))
for instance to sort the files by mtime (use oL
for -S
, and n
for -V
).
To remove all but the two most recently modified regular files:
rm -f -- *(D.om[3,-1])
¹ there are still some length limitations (by execve()
and in some non-GNU xargs
implementations much lower arbitrary ones), and some non-GNU xargs
implementations will choke of input that contains sequences of bytes not forming valid characters.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
10
down vote
accepted
In Linux, any character is a valid filename constituting character except:
(ASCII NUL): as used for string termination in C
/
(forward slash): as used for path separation
So, your approach will definitely not work in many cases as you can imagine e.g. does it handle a newline (n
) in filename? (Hint: No).
Few notes:
- Don't parse
ls
; use dedicated tools (there is at least one for most use cases) - When dealing with filenames, try to leverage the NUL separated output provided by almost all GNU tools that work with such data
- Take care when piping, make sure both programs can understand NUL separations
- Whenever you're invoking
xargs
, see if you can get away withfind ... -exec
; in most cases, you will be fine with justfind
alone
I think these will get you going for now. steeldriver already provided the NUL separated idea in the comment (printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use this as a starting point.
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look intofind
as well, thanks for the suggestion.
– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases yourls
parsing approach would fail e.g. did you take into account a newline in filename?
– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what doeshead -z
do? It sounds ridiculous but I don't haveman
norinfo
in my CoreOS container linux... Couldn't find in the internet either. I gethead: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNUhead
(comes with GNUcoreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
– heemayl
Sep 5 at 13:54
 |Â
show 3 more comments
up vote
10
down vote
accepted
In Linux, any character is a valid filename constituting character except:
(ASCII NUL): as used for string termination in C
/
(forward slash): as used for path separation
So, your approach will definitely not work in many cases as you can imagine e.g. does it handle a newline (n
) in filename? (Hint: No).
Few notes:
- Don't parse
ls
; use dedicated tools (there is at least one for most use cases) - When dealing with filenames, try to leverage the NUL separated output provided by almost all GNU tools that work with such data
- Take care when piping, make sure both programs can understand NUL separations
- Whenever you're invoking
xargs
, see if you can get away withfind ... -exec
; in most cases, you will be fine with justfind
alone
I think these will get you going for now. steeldriver already provided the NUL separated idea in the comment (printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use this as a starting point.
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look intofind
as well, thanks for the suggestion.
– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases yourls
parsing approach would fail e.g. did you take into account a newline in filename?
– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what doeshead -z
do? It sounds ridiculous but I don't haveman
norinfo
in my CoreOS container linux... Couldn't find in the internet either. I gethead: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNUhead
(comes with GNUcoreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
– heemayl
Sep 5 at 13:54
 |Â
show 3 more comments
up vote
10
down vote
accepted
up vote
10
down vote
accepted
In Linux, any character is a valid filename constituting character except:
(ASCII NUL): as used for string termination in C
/
(forward slash): as used for path separation
So, your approach will definitely not work in many cases as you can imagine e.g. does it handle a newline (n
) in filename? (Hint: No).
Few notes:
- Don't parse
ls
; use dedicated tools (there is at least one for most use cases) - When dealing with filenames, try to leverage the NUL separated output provided by almost all GNU tools that work with such data
- Take care when piping, make sure both programs can understand NUL separations
- Whenever you're invoking
xargs
, see if you can get away withfind ... -exec
; in most cases, you will be fine with justfind
alone
I think these will get you going for now. steeldriver already provided the NUL separated idea in the comment (printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use this as a starting point.
In Linux, any character is a valid filename constituting character except:
(ASCII NUL): as used for string termination in C
/
(forward slash): as used for path separation
So, your approach will definitely not work in many cases as you can imagine e.g. does it handle a newline (n
) in filename? (Hint: No).
Few notes:
- Don't parse
ls
; use dedicated tools (there is at least one for most use cases) - When dealing with filenames, try to leverage the NUL separated output provided by almost all GNU tools that work with such data
- Take care when piping, make sure both programs can understand NUL separations
- Whenever you're invoking
xargs
, see if you can get away withfind ... -exec
; in most cases, you will be fine with justfind
alone
I think these will get you going for now. steeldriver already provided the NUL separated idea in the comment (printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
), use this as a starting point.
edited Sep 5 at 13:56
answered Sep 4 at 18:00


heemayl
64k8127203
64k8127203
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look intofind
as well, thanks for the suggestion.
– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases yourls
parsing approach would fail e.g. did you take into account a newline in filename?
– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what doeshead -z
do? It sounds ridiculous but I don't haveman
norinfo
in my CoreOS container linux... Couldn't find in the internet either. I gethead: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNUhead
(comes with GNUcoreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
– heemayl
Sep 5 at 13:54
 |Â
show 3 more comments
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look intofind
as well, thanks for the suggestion.
– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases yourls
parsing approach would fail e.g. did you take into account a newline in filename?
– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what doeshead -z
do? It sounds ridiculous but I don't haveman
norinfo
in my CoreOS container linux... Couldn't find in the internet either. I gethead: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNUhead
(comes with GNUcoreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
– heemayl
Sep 5 at 13:54
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look into
find
as well, thanks for the suggestion.– Pedro A
Sep 5 at 13:39
Thanks for your answer :) I think you should quote steeldriver's comment instead of just mentioning (since comments are not permanent). I will take a look into
find
as well, thanks for the suggestion.– Pedro A
Sep 5 at 13:39
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
I have one question though: I don't understand what you mean by "your approach will not definitely work in many cases as you can imagine" - "not work" as in "not safe" or "not unsafe"? Because "your approach" refers to me and not to the malicious user, and your prior statements are in my favor, so I am confused.
– Pedro A
Sep 5 at 13:40
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases your
ls
parsing approach would fail e.g. did you take into account a newline in filename?– heemayl
Sep 5 at 13:46
@PedroA You are you :) Like i said, as all characters are valid except the mentioned two, you should be able to imagine the numerous cases your
ls
parsing approach would fail e.g. did you take into account a newline in filename?– heemayl
Sep 5 at 13:46
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what does
head -z
do? It sounds ridiculous but I don't have man
nor info
in my CoreOS container linux... Couldn't find in the internet either. I get head: invalid option 'z'
– Pedro A
Sep 5 at 13:51
Oh, a newline in the filename... I hadn't thought of that. If you don't mind adding that to your answer too :) Also, sorry to ask, but what does
head -z
do? It sounds ridiculous but I don't have man
nor info
in my CoreOS container linux... Couldn't find in the internet either. I get head: invalid option 'z'
– Pedro A
Sep 5 at 13:51
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNU
head
(comes with GNU coreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html– heemayl
Sep 5 at 13:54
@PedroA Newline is just one case, there are many such as you might have guessed. You need GNU
head
(comes with GNU coreutils
). Here's the online version: manpages.ubuntu.com/manpages/xenial/man1/head.1.html– heemayl
Sep 5 at 13:54
 |Â
show 3 more comments
up vote
3
down vote
xargs
does support some quoting: with single quotes, double quotes or backslash which allows it to accept arbitrary arguments¹, but with a syntax that is different from the Bourne-like shells' quoting syntax.
The GNU implementation of ls
as found on Ubuntu doesn't have any quoting mode that is compatible with the xargs
input format.
Its ls --quoting-style=shell-always
is compatible with ksh93, bash and zsh shells quoting syntax, but only when the output of ls
is interpreted by the shell in the same locale as ls
was when it output it. Also, some locales, like those using BIG5, BIG5-HKSCS, GBK or GB18030 should be avoided.
So with those shells, you can actually do:
typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s' "$files[@]:0:3") ...
But that has little advantage over:
files=(*(N)) # zsh
files=(~(N)*) # ksh93
shopt -s nullglob; files=(*) # bash
The only case where it becomes useful is when you want to use the -t
option of ls
to sort the files by mtime/atime/ctime or -S
/-V
. But even then, you might as well use zsh
's:
files=(*(Nom))
for instance to sort the files by mtime (use oL
for -S
, and n
for -V
).
To remove all but the two most recently modified regular files:
rm -f -- *(D.om[3,-1])
¹ there are still some length limitations (by execve()
and in some non-GNU xargs
implementations much lower arbitrary ones), and some non-GNU xargs
implementations will choke of input that contains sequences of bytes not forming valid characters.
add a comment |Â
up vote
3
down vote
xargs
does support some quoting: with single quotes, double quotes or backslash which allows it to accept arbitrary arguments¹, but with a syntax that is different from the Bourne-like shells' quoting syntax.
The GNU implementation of ls
as found on Ubuntu doesn't have any quoting mode that is compatible with the xargs
input format.
Its ls --quoting-style=shell-always
is compatible with ksh93, bash and zsh shells quoting syntax, but only when the output of ls
is interpreted by the shell in the same locale as ls
was when it output it. Also, some locales, like those using BIG5, BIG5-HKSCS, GBK or GB18030 should be avoided.
So with those shells, you can actually do:
typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s' "$files[@]:0:3") ...
But that has little advantage over:
files=(*(N)) # zsh
files=(~(N)*) # ksh93
shopt -s nullglob; files=(*) # bash
The only case where it becomes useful is when you want to use the -t
option of ls
to sort the files by mtime/atime/ctime or -S
/-V
. But even then, you might as well use zsh
's:
files=(*(Nom))
for instance to sort the files by mtime (use oL
for -S
, and n
for -V
).
To remove all but the two most recently modified regular files:
rm -f -- *(D.om[3,-1])
¹ there are still some length limitations (by execve()
and in some non-GNU xargs
implementations much lower arbitrary ones), and some non-GNU xargs
implementations will choke of input that contains sequences of bytes not forming valid characters.
add a comment |Â
up vote
3
down vote
up vote
3
down vote
xargs
does support some quoting: with single quotes, double quotes or backslash which allows it to accept arbitrary arguments¹, but with a syntax that is different from the Bourne-like shells' quoting syntax.
The GNU implementation of ls
as found on Ubuntu doesn't have any quoting mode that is compatible with the xargs
input format.
Its ls --quoting-style=shell-always
is compatible with ksh93, bash and zsh shells quoting syntax, but only when the output of ls
is interpreted by the shell in the same locale as ls
was when it output it. Also, some locales, like those using BIG5, BIG5-HKSCS, GBK or GB18030 should be avoided.
So with those shells, you can actually do:
typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s' "$files[@]:0:3") ...
But that has little advantage over:
files=(*(N)) # zsh
files=(~(N)*) # ksh93
shopt -s nullglob; files=(*) # bash
The only case where it becomes useful is when you want to use the -t
option of ls
to sort the files by mtime/atime/ctime or -S
/-V
. But even then, you might as well use zsh
's:
files=(*(Nom))
for instance to sort the files by mtime (use oL
for -S
, and n
for -V
).
To remove all but the two most recently modified regular files:
rm -f -- *(D.om[3,-1])
¹ there are still some length limitations (by execve()
and in some non-GNU xargs
implementations much lower arbitrary ones), and some non-GNU xargs
implementations will choke of input that contains sequences of bytes not forming valid characters.
xargs
does support some quoting: with single quotes, double quotes or backslash which allows it to accept arbitrary arguments¹, but with a syntax that is different from the Bourne-like shells' quoting syntax.
The GNU implementation of ls
as found on Ubuntu doesn't have any quoting mode that is compatible with the xargs
input format.
Its ls --quoting-style=shell-always
is compatible with ksh93, bash and zsh shells quoting syntax, but only when the output of ls
is interpreted by the shell in the same locale as ls
was when it output it. Also, some locales, like those using BIG5, BIG5-HKSCS, GBK or GB18030 should be avoided.
So with those shells, you can actually do:
typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s' "$files[@]:0:3") ...
But that has little advantage over:
files=(*(N)) # zsh
files=(~(N)*) # ksh93
shopt -s nullglob; files=(*) # bash
The only case where it becomes useful is when you want to use the -t
option of ls
to sort the files by mtime/atime/ctime or -S
/-V
. But even then, you might as well use zsh
's:
files=(*(Nom))
for instance to sort the files by mtime (use oL
for -S
, and n
for -V
).
To remove all but the two most recently modified regular files:
rm -f -- *(D.om[3,-1])
¹ there are still some length limitations (by execve()
and in some non-GNU xargs
implementations much lower arbitrary ones), and some non-GNU xargs
implementations will choke of input that contains sequences of bytes not forming valid characters.
edited 4 hours ago
answered Sep 5 at 16:40
Stéphane Chazelas
1,044915
1,044915
add a comment |Â
add a comment |Â
Pedro A is a new contributor. Be nice, and check out our Code of Conduct.
Pedro A is a new contributor. Be nice, and check out our Code of Conduct.
Pedro A is a new contributor. Be nice, and check out our Code of Conduct.
Pedro A is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1072087%2fis-quoting-filenames-enough-security-for-running-xargs-sudo-rm-rf%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
Have you considered doing something like
printf -- '%s' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?– steeldriver
Sep 4 at 17:45
Can a file with the character
/
in the name be created I am trying to achieve this back here– George Udosen
Sep 4 at 17:52
3
@George No, a filename cannot contain a slash.
– wjandrea
Sep 4 at 17:54
So when OP says clever person I was wondering...
– George Udosen
Sep 4 at 17:55
5
Simply because you're parsing
ls
output this is already a poorly written command, even with quoting.ls
also uses locale for sorting order, I think, so I don't see what's the purpose ofhead
in removing last 2 ( unless you're trying to get rid of.
and..
which iirc aren't allowed as arguments torm
anyway. Just usefind /path/to/folder -type f delete
. And nosudo
if you run from cron - cron is already at root level– Sergiy Kolodyazhnyy
Sep 4 at 19:35