diff --git a/recon_surf/functions.sh b/recon_surf/functions.sh index 801be99b7..5e03aee64 100644 --- a/recon_surf/functions.sh +++ b/recon_surf/functions.sh @@ -225,15 +225,16 @@ function check_allow_root() function softlink_or_copy() { + # Creates a symlink at file pointing to target; if that fails, for example because symlinks are not supported by the + # file system, copy the file instead. The baseline call is `ln -sf $1 $2 >> $3`. # params - # 1: file - # 2: target + # 1: link target (or file copy source) -> path to target of link / absolute or relative but relative to **file**!! + # 2: link (or file copy destination) -> path to link file / absolute or relative to cwd # 3: logfile # 4: cmdf - local LF="$3" - local ln_cmd=(ln -sf "$1" "$2") - local cp_cmd=(cp "$1" "$2") + local LF="$3" link_tgt_cp_src="$1" link_cp_dest="$2" if [[ $# -lt 3 ]] || [[ -z "$LF" ]] ; then echo "WARNING: Parameter 3 of softlink_or_copy missing!" ; fi + local ln_cmd=(ln -sf "$link_tgt_cp_src" "$link_cp_dest") if [[ $# -eq 4 ]] then local CMDF=$4 @@ -242,8 +243,13 @@ function softlink_or_copy() echo "$timecmd $(echo_quoted "${ln_cmd[@]}")" echo "if [[ \${PIPESTATUS[0]} != 0 ]]" echo "then" - echo " echo $(echo_quoted "${cp_cmd[@]}")" - echo " $timecmd $(echo_quoted "${cp_cmd[@]}")" + if [[ "$link_tgt_cp_src" != /* ]] ; then # relative path, defined with respect to $link_cp_dest + echo " src=\$(dirname $(echo_quoted "$link_cp_dest"))/$(echo_quoted "$link_tgt_cp_src")" + else + echo " src=$(echo_quoted "$link_tgt_cp_src")" + fi + echo " echo \"cp \\\"\$src\\\" $(echo_quoted "$link_cp_dest")\"" + echo " $timecmd cp \"\$src\" $(echo_quoted "$link_cp_dest")" echo " if [[ \${PIPESTATUS[0]} != 0 ]] ; then exit 1 ; fi" echo "fi" } | tee -a "$CMDF" @@ -253,8 +259,9 @@ function softlink_or_copy() $timecmd "${ln_cmd[@]}" 2>&1 if [[ "${PIPESTATUS[0]}" != 0 ]] then - echo_quoted "${cp_cmd[@]}" - $timecmd "${cp_cmd[@]}" 2>&1 + if [[ "$link_tgt_cp_src" != /* ]] ; then link_tgt_cp_src="$(dirname "$2")/$link_tgt_cp_src" ; fi # relative path + echo_quoted "cp" "$link_tgt_cp_src" "$link_cp_dest" + $timecmd "cp" "$link_tgt_cp_src" "$link_cp_dest" 2>&1 if [[ "${PIPESTATUS[0]}" != 0 ]] ; then exit 1 ; fi fi } | tee -a "$LF" @@ -262,6 +269,19 @@ function softlink_or_copy() fi } +function relative_to() +{ + # Generate a relative path from $2 to $3, so `ln -s $(relative_to python /path/src /path/target) /path/src` is valid. + # params + # $1: python executable + # $2: base path whose directory is used as the starting point (e.g., the link path; start dir is dirname($2)) + # $3: target path to compute the relative path to (normal shell quoting is allowed) + script=('import sys, os' + 'base, target = sys.argv[sys.argv.index("-c")+1:]' + 'print(os.path.relpath(target, start=os.path.dirname(base)))') + $1 -c "$(printf "%s\n" "${script[@]}")" "$2" "$3" +} + function echo_quoted() { # params ... 1-N diff --git a/run_fastsurfer.sh b/run_fastsurfer.sh index 471790a3e..9a18156dc 100755 --- a/run_fastsurfer.sh +++ b/run_fastsurfer.sh @@ -1102,7 +1102,13 @@ then exit 1 fi # create a symlink of the stats file for the old file name - softlink_or_copy "$asegdkt_vinn_statsfile" "$asegdkt_statsfile" "$seg_log" + # at this point, $asegdkt_vinn_statsfile might be an absolute path, which causes problems in containers, so make + # the path relative, if both statsfiles are in $subject_dir (which will be almost always). + if [[ "$asegdkt_vinn_statsfile" == "$subject_dir/"* ]] && [[ "$asegdkt_statsfile" == "$subject_dir/"* ]] + then asegdkt_vinn_statsfile_=$(relative_to "$python" "$asegdkt_statsfile" "$asegdkt_vinn_statsfile") + else asegdkt_vinn_statsfile_=$asegdkt_vinn_statsfile + fi + softlink_or_copy "$asegdkt_vinn_statsfile_" "$asegdkt_statsfile" "$seg_log" # create the aseg only statsfile mask_name_manedit=$(add_file_suffix "$mask_name" "manedit") if [[ -e "$mask_name_manedit" ]] ; then mask_name="$mask_name_manedit" ; fi