web-dev-qa-db-ja.com

ターゲットファイルを(文字通り)開くシンボリックリンクを作成する方法

ディレクトリfoo内にファイルbar.txtがあり、baz.txtへのシンボリックリンクfoo/bar.txtを作成するとします。お気に入り:

./foo
./foo/bar.txt
./baz.txt -> foo/bar.txt

baz.txtを開くと、エディターはbaz.txtがディレクトリ.で開かれていると見なします。むしろbar.txtが(文字通り)開かれるようなリンクを作成する方法はありますか?

コンテキスト(またはこれを実行しようとしている理由):同じディレクトリに残っている.odtファイル内に、インデックスを付けてコメントするファイルの大規模なコレクションを含むディレクトリがあります。この.odtファイルでは、ディレクトリ内のインデックス付きファイルへのハイパーリンクを作成します。これにより、ファイル名だけでなく、(はるかに)多くのコンテキストで個々のファイルに簡単にアクセスできます。ハイパーリンクを相対パスとして保存するようにLibreOfficeを設定しました。これにより、これらのリンクがすべてのコンピューターで機能するようになります。コンピューターは、ユーザーファイルに対して常に同じディレクトリツリーを持っているとは限りません。

この.odtファイルへのシンボリックリンク(または同等のもの)を作成したいのですが、(上記の例では)リンクがbaz.txtを開く場合は、相対パス(の観点から) LibreOffice)は間違っています。以前に作成されたハイパーリンクは機能しません。また、baz.txtでハイパーリンクを作成した場合(もちろん、比喩的に)、元のbar.txtでは機能しません。

6
gusbrs

いいえ。ただし、シンボリックリンクである各引数を取り、それを$(readlink -f $the_symlink)に変換するlibreofficeラッパーを作成できます。次に、そのラッパーを介してlibreofficeファイルを開くようにファイルマネージャーを設定できます。

lowrapper:

#!/bin/bash -e
args=()
for a; do
    case $a in 
        -*) args+=("$a");;  #skip flags (your file names don't start with -, right?)
        *)  if ! [ -L "$a" ]; then #not a link
                args+=("$a")
            else #link => target
                args+=( "$( readlink -f "$a")" )
            fi
            ;;
    esac
done
libreoffice "${args[@]}"

今あなたがchmod +x lowrapper、それをPATHのディレクトリに置き、libreofficeファイルのハンドラープログラムをlibreofficeからlowrapperに変更すると、libreofficeはリンクではなくリンクターゲットを開きます。

12
PSkocik

できませんが、代わりにできることは、次のように「foo」ディレクトリへのシンボリックリンクを作成することです。

./foo
./foo/root -> .
./root -> foo/.

次に、すべてのハイパーリンクの先頭に「root」を追加します。これで、「。」からドキュメントを開くと、「root」は「foo /。」に解決され、「root /baz.txt」は「foo /./ baz.txt」に解決されます。 「foo」自体から開くと、「root」は「。」を指すため、同じ「root /baz.txt」は「./baz.txt」に解決されます。

3

私はあなたが求めていることを正確に行う方法はないと思います。シンボリックリンクはファイルシステムの構成要素です。ただし、リンクの代わりにリンクターゲットを開く小さなスクリプトを作成すると、適切な回避策が存在する可能性があります。

#!/bin/bash

i=0
declare -a targets
for file in "$@"; do
        targets[$i]="$(readlink -f "$file")"
        ((i++))
done
libreoffice "${targets[@]}"

それをPATHに、たとえば~/bin/openLink.shとして保存し、実行可能にします。

chmod a+x ~/bin/openLink.sh`

次に、ファイルマネージャを開き(cajaと言いました)、.odtファイルを右クリックして、[プログラムから開く] => [その他のアプリケーション]を選択します。

open with dialog

[カスタムコマンドを使用する]をクリックして、スクリプトをそこに配置します。

custom command dialog

最後に、すべてを閉じます。これで、.odtファイルをクリックするたびに、そのラッパーを使用してファイルが開かれるため、ターゲットディレクトリ内のすべてのリンクが開かれるはずです。通常のファイルのreadlink -fはファイルの名前を返すだけなので、これは非リンクでも機能することに注意してください。

3
terdon

開くファイルの(相対)パスを含む新しいファイルタイプ(「sim(ulated)link」と呼びましょう)を作成し、スクリプトを作成するという、やや異なるアプローチに従うことになりました。それに対処します。

次のシナリオを検討してください。

./dir1/dir11/foo.odt
./dir2/foo.odl

「OpenDocumentリンク」の「odl」。 「foo.odl」の内容は次のとおりです。

../dir1/dir11/foo.odt

次に、次のスクリプトを作成して*.odlを開くことができます(terdonの回答から採用)。

#!/bin/bash

declare -a targets
for file in "$@"; do
    targets+=( "$(readlink -f "$( dirname "$file" )"/"$( <"$file" )")" )
done
libreoffice "${targets[@]}"

(このように指定されたパスがシンボリックリンクの場合にリンクをたどるため、readlinkを使用したくない場合は、次のように入力できます:)

#!/bin/bash

for file in "$@"; do
    cd "$( dirname "$file" )"
    libreoffice "$( <"$file" )"
done

次に、このスクリプトをファイルマネージャーの.odlファイルに関連付けることができます(terdonの回答で説明されています)。最終的には、.odlファイルのmimeタイプを作成し、それをスクリプトに関連付ける必要があります(私の場合、この手順が欠けていても機能しましたが、すべてのプレーンテキストファイルをスクリプトに関連付けました。これは明らかに望ましくありませんでした)。

PSkocikとterdonが提供するものよりも、完全に正常に機能するのに、なぜこの代替手段を好んだのですか? 3つの理由:

  • 私の.odtファイル(およびそれらへのリンク)のすべてが、「ターゲットファイルのディレクトリで」それらを開かなければならないこの構造を持っているわけではありません。このように、関心のあるファイルのオープン手順にのみ影響します。

  • システムの通常のシンボリックリンクは、現在のコンピューターの設定に関係なく機能します。つまり、スクリプトで.odtファイルを開くように設定を変更しなかったコンピューターでこれらのファイルのいずれかを開いた場合、それはとにかく開き、誤ってパスを台無しにする可能性があります。その中の私のハイパーリンクの。このように、コンピューターが.odlファイルを開くように設定されていない場合、それらは単に機能せず、ターゲットファイルを直接検索する必要があります。

  • 最後に、関連するディレクトリの一部を移動または名前変更した場合、.odlファイルを簡単に検索および置換して、パスを修正できます。 (これはシンボリックリンクでも実行できる可能性がありますが、やや難しいようです)。

警告:これは、.odlファイルで指定された整形式で冗長性のない相対パスに対してのみ機能すると思います。絶対パスまたはある程度の冗長性を備えた相対パスでも機能するという意味で、より堅牢に物事を行う方法がおそらくあります。

0
gusbrs