ovedpo15 has asked for the wisdom of the Perl Monks concerning the following question:
In that case, the bash script will look like:touch /a/b/c/d1
The utility works good, unless a path contains "special chars".mkdir -p /tmp/a/b/c cp /a/b/c/d1 /tmp/a/b/c # Or: rsync -a $USER@MACHINE:/a/b/c/d1 /tmp/a/b/c
I also tried to use quotemeta:sub escape { my ($path) = @_; if ($path =~ /\\/) { $path =~ s/\\/\\\\/g; } if ($path =~ /\$/) { $path =~ s/\$/\\\$/g; } return $path; } sub wrap_with_quotes { my ($path) = @_; if ($path =~ /( |\;|\!)/) { return '"'.$path.'"'; } return $path; }
But it also failed for a lot of cases and it escaped alot of unneeded chars (like ".", "/", etc. - which are valid in paths without escaping).sub escape { my ($path) = @_; my $new_path = quotemeta($path); $new_path =~ s/\\\//\//g; return $new_path; }
I of course want to support any kind of path. For example, the special char could contain a "\" before it, and then I need to escape both of them. I built a small test for you to understand what I'm after:foreach my $dir (sort(keys(%dirs))) { $dir = escape($dir); $dir = wrap_with_quotes($dir); print("mkdir -p /tmp/$dir\n"); } foreach my $file (sort(keys(%files))) { my $parent_dir = dirname($file); my $abs_path = abs_path($file); $abs_path = escape($abs_path); $abs_path = wrap_with_quotes($abs_path); $parent_dir = escape($parent_dir); $parent_dir = wrap_with_quotes($parent_dir); print("cp $abs_path /tmp/$parent_dir\n"); } foreach my $file (sort(keys(%remote_files))) { my $parent_dir = dirname($file); my $abs_path = abs_path($file); my $host = get_host(); $abs_path = escape($abs_path); $abs_path = wrap_with_quotes($abs_path); $parent_dir = escape($parent_dir); $parent_dir = wrap_with_quotes($parent_dir); print("rsync -a $host$abs_path /tmp/$parent_dir\n"); }
If 1 is passed to the script, it will generate directory with one special char (for example: test1/a;b).declare -a special_chars=("!" "@" "#" "$" "%" "^" "_" "-" "=" "+" "[" +"]" "(" ")" "{" "}" "'" ":" "," "." ";" " " "\"" "<" ">") if [ "$1" == 1 ]; then # create playground (before running the bash sc +ript) for special_char in "${special_chars[@]}"; do mkdir -p "/test1/a${special_char}b" touch "/test1/a${special_char}b/data" done else # test playground output (after running the bash script) for special_char in "${special_chars[@]}"; do mkdir -p "/tmp/test1/a${special_char}b" if [ "$?" -ne 0 ]; then exit 1 fi done fi
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Escape special chars in a path
by choroba (Cardinal) on Aug 17, 2022 at 18:25 UTC | |
by afoken (Chancellor) on Aug 18, 2022 at 13:51 UTC | |
Re: Escape special chars in a path
by johngg (Canon) on Aug 17, 2022 at 21:26 UTC | |
Re: Escape special chars in a path
by kcott (Archbishop) on Aug 18, 2022 at 01:38 UTC | |
Re: Escape special chars in a path
by tybalt89 (Monsignor) on Aug 18, 2022 at 22:40 UTC | |
by afoken (Chancellor) on Aug 21, 2022 at 10:23 UTC |