SHELL := /bin/bash .PHONY: test test: clean prepare echo $$'#!/bin/bash\ntarget=top2\nmkdir -p $$target/top' > 1.sh ./1.pl top >> 1.sh chmod u+x 1.sh ./1.sh diff -r top top2/top .PHONY: prepare prepare: mkdir -p top/usr mkdir -p top/root/site/tools/gauv/python3/3.6.3/{lib,bin} touch top/root/site/tools/gauv/python3/3.6.3/bin/python3.6 ln -s $(PWD)/top/root/site/tools/gauv top/usr/vsa ln -s 3.6.3 top/root/site/tools/gauv/python3/3.6.3a .PHONY: clean clean: rm -rf top top2 1.sh #### #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Path::Tiny qw{ path }; my $path = path(shift); my $paths = $path->visit( sub { $_[1]->{$_} = (-f) ? 'file' : (-l) ? [readlink] : (-d) ? 'dir' : 'unknown' }, { recurse => 1 } ); my @links; for my $found (sort { length $a <=> length $b } keys %$paths) { if ('file' eq $paths->{$found}) { say qq(cp '$found' "\$target/$found"); } elsif ('dir' eq $paths->{$found}) { say qq(mkdir "\$target/$found"); } elsif (ref [] eq ref $paths->{$found}) { my $to = path($paths->{$found}[0]); $to = $to->relative(path($found)->absolute->parent) if $to->is_absolute; my $source = path('$target', $found); push @links, qq(ln -s "$to" "$source"); } } say for @links;