これはABBYYの企業ブログですが、この記事では製品と当社については触れませんが、1つの実用的な問題の解決策について説明します。MicrosoftDFS(Distributed File System)を使用する状況でのMac OS Xからのネットワークリソースへのアクセスです。 大企業では、このテクノロジーはあらゆる場面で使用されており、ABBYYも例外ではありません。 実際、リソースが分散しているサーバーの異種システムではなく、ネットワークリソースの論理的に配置されたツリーが表示されます。
5年前、仕事用のラップトップをMacBook Proに変更することを決めたとき、チームは複雑な気持ちで迎えられました。 これは、システム管理者のチームについて特に懐疑的でした。 私は過去5年間にわたってこのチームを率いていましたが、私は非常にわずかな免罪符を持つことになっており、管理者の観点からはMac OSの使用は単なる免罪符を超えていました。 しかし、私はすべての問題を自分自身に負わせると言って、ほとんど私の言葉を守りましたが、時々、私は時々、私の管理者を私のマックの問題で悩まさなければなりませんでした。 しかし、私はDFSの問題を自分で解決することができました。
DFSへのアクセスの問題は長い間フォーラムで議論されてきました。すべての関心のある人は、数年間Appleからのこの技術の通常のサポートを待っていました。 しかし、残念ながら、物事はまだそこにあります(クパチーノではどうやら)。
この問題の概要を簡単に説明します。定期的にファイルへのUNC形式のリンクが記載された手紙を受け取ります。
\\dfs\Common\Media\Pictures\New Year Party\Aram on his head.jpg
Outlookの最新バージョンでは、次のようなURLリンクを文字に自動的に挿入し始めました。
file:////dfs/Common/Media/Pictures/New%20Year%20Party/…
Mac OSはこのリンクに使用するプロトコルを知らないので、私にとってこれは不満です。 運が良ければ、Outlookはリンク自体を配置しなかったので、Snow LeopardのMail.appはUNCパスを自動的に
smb://server/share/path
変換できます
smb://server/share/path
。 優れた機能ですが、それを助けるには、非常に幸運である必要があります。ソースパスはDFSリソースへのリンクであってはならず、リンクはHTMLテキストに埋め込まれてはいけません。 さらに、Mail.appの熱意は、最初に発生したギャップで途切れます。したがって、非常に頻繁にそのような自動リンクも壊れます。 しかし、Finderで「サーバーに接続」ウィンドウを開き、ペンでソーステキストをコピーし、すべてのバックスラッシュを直接に修正します。ソースパスが実際のコンピューターへの実際のパスであり、DFSパスではない場合のみすべてが機能します。
ADmitMacと呼ばれるこの問題に対するグローバルな解決策があることを認めなければなりませんが、それは多くの費用がかかり、他の多くのことを行います。
Diffissと呼ばれる2番目の簡単なソリューションは、初心者プログラマーの実験的な作業に似ています。 ただし、この製品では、メインアプリケーションウィンドウが閉じられるまでDFSツリーをナビゲートできます。その後、アプリケーションウィンドウを閉じると、アプリケーションを再起動しない限り開くことができません。 このプログラムを使用すると、DFSノードと実サーバーとの対応を意識せずに、DFSツリーをたどることができますが、文字からのリンクを開くことはできません。 ハンドルは、まずDiffiss内、次にFinder内で木の上を歩く必要があります。 しかし、しばらくの間、これでも安心でした。
最近、私は
ここで
この記事を偶然偶然見つけて、問題の徹底的な解決策を講じました。つまり、最終的にAppleがFinderレベルでシステム自体のDFSをサポートするまでにつまずくために、しっかりした松葉杖を作りました。 ところで、OS X Snow Leopardに付属のSamba 3.0.28では、DFSでの作業がサポートされています(実際に使用しました)。
松葉杖は2つの部分で構成されています。 1つは、入力としてDFSルートサーバーの名前とソースパスを受け取り、実サーバー上のディレクトリへのUNCパスを出力するbashスクリプトです。 2番目の詳細は、ユーザーのソースパスを取得し、bashスクリプトを実行し、Finderで目的のディレクトリを開く小さなAppleScriptスクリプトです。
それぞれの詳細を個別に検討してください。
#!/ bin / bash
#このスクリプトは、DFSパスをリソースに変換するように設計されています
#Windowsネットワーク上の実際の共有リソースへのパス
#スクリプトは入力で待機しています:
#arg1:DFSルートサーバー名
#arg2:実際のパスにキャストされるUNCパス
#スクリプトは、ユーザー認証がKerberosを介して行われることを前提としています。
if [ -z "$ 1" ] || [ -z "$ 2" ] ; それから
echo -e "エラー:スクリプトには2つの引数があります。"
エコー
100 番出口
fi
DFS_SERVER = 1ドル
#バックスラッシュをフォワードスラッシュに変換し、先頭のスペースを削除します
#行を書き、すべての文字を小文字に変換します
DFS_PATH = $ ( echo -n $ 2 | sed 's / \\ / \ // g' | sed 's / ^ * // g' | tr "[:upper:]" "[:lower:]" )
real_share = ""
exit_code = "0"
#rpcclientを使用してDFSノードのリストを取得します(ループの最後にある式を参照して、
#「完了」の直後)。 コマンドを呼び出すこのメソッドは、回避するために作成されます
#チャネルの使用、チャネルの実装に関しては、ループはサブシェルで実行され、
#ループで変更する変数をマスクします。
読み取り中 smb_path; する
コメントを読む
状態を読む
num_storesを読み取ります
#ラベルからフィールドを分離し、先頭のスペースを削除し、文字を小文字に変換します
smb_path = $ ( echo $ smb_path | awk -F: '{gsub(/ ^ [\ t] + /、 ""、$ 2); print $ 2}' | \
tr "[:upper:]" "[:lower:]" )
num_stores = $ ( echo $ num_stores | awk -F: '{gsub(/ ^ [\ t] + /、 ""、$ 2); print $ 2}' )
state = $ ( echo $ state | awk -F: '{gsub(/ ^ [\ t] + /、 ""、$ 2); print $ 2}' )
#数値と状態が変数num_storesとstateに入力されていることを確認します
#空ではないこと。 そうでない場合は、おそらく障害が発生しています
expr " $ num_stores + $ state " > / dev / null 2 > / dev / null
if [ $? ! = 0 ] || [ -z " $ num_stores " ] || [ -z " $ state " ] ; それから
echo -e "DFSホストのリストを取得中にエラーが発生しました。"
exit_code = "200"
破る
fi
#ノードに関連付けられた実リソースの数は複数にすることができます。
#このような場合、smbclient呼び出しを使用してリソースを選択します。
for ( ( store = 0 ; store < $ num_stores ; store ++ ) )) ; する
読み取りサーバー
共有を読む
やった
#DFSパスの先頭がいずれかのリソースと一致するかどうかを確認します
#受信したリストから
if [ " $ state " -eq "1" ] && [ [ " $ DFS_PATH " == " $ smb_path " * ] ] ; それから
if [ " $ num_stores " -gt "1" ] ; それから
#ノードごとのリソースの数が複数の場合、smbclientを呼び出します。
#問題は2行で構成されています。
バフを 読み ながら ; する
もし [ ! -z " $ buff " ] && [ [ " $ buff " == "//" * ] ] ; それから
real_share = " $ buff " ;
他に
#2行目が見えない場合
#リソースへのUNCパスとして、エラーが発生した
echo -e "smbclientの呼び出しエラー: $ buff "
exit_code = "300"
fi
done << ( smbclient -k -c showconnect $ smb_path 2 > / dev / null )
他に
server = $ ( echo $ server | awk -F: '{gsub(/ ^ [\ t] + /、 ""、$ 2); print $ 2}' )
share = $ ( echo $ share | awk -F: '{gsub(/ ^ [\ t] + /、 ""、$ 2); print $ 2}' )
real_share = "// $ server / $ share "
fi
#残りのUNCパスを実サーバーとリソースに追加します
もし [ ! -z " $ real_share " ] ; それから
smb_path_len = " $ {#smb_path} "
rest_of_path = $ ( awk -v len = " $ smb_path_len " -v awk_string = " $ DFS_PATH " \
'BEGIN {print substr(awk_string、len + 1)}' )
real_share = " $ real_share $ rest_of_path "
fi
#最初の一致まで検索するため、ループを抜けます
破る
fi
done << ( rpcclient -k --command = "dfsenum 3" $ DFS_SERVER | sed 's / \\ / \ // g' )
#real_shareに値が割り当てられていない場合(ほとんどの場合
#ソースパスがリストで見つからなかったか、エラーが発生したため
#元のパスを返す
if [ -z " $ real_share " ] ; それから
real_share = $ DFS_PATH
fi
#結果をAppleScriptに返すには、出力する必要があります
#標準出力へ
echo $ real_share
exit $ exit_code
もちろん、スクリプトは完璧ではありません。すべてが確実に改善されます。 一般的に、私はスクリプトを書くことはめったにありません; Mac OSユーザーは通常それらを必要としないので、私はまだ私の手を満たしていません。 技術的な詳細はコメントから明らかですが、基本的に次のことを行います。
- Sambaパッケージの一部であるrpcclientプログラムを使用して、実サーバーにリンクされたノードテーブルをDFSルートサーバーから学習します。 ここでは、スクリプトはKerberosを介した認証を前提としていることに注意してください。これは、コンピューターがドメインにリストされ、ドメイン名とパスワードで既にログインしていることを意味します。 それがなければ、Windowsサーバー環境での生活は非常に厳しいものになります。
- 次に、結果のテーブルを分析します(上記の記事ではrpcclientの出力の構造について説明しているため、ここでは繰り返しません)。 ノードが解析されると、元のパスの先頭に一致するノードを探します。 見つかったらすぐに、さらに検索を停止し、パーツからの実際のパスを作成し、echoコマンドで表示します。 これは、作業結果をシェルからAppleScriptに転送する標準的な方法です。
このストーリー全体に1つの特徴があります。 実際、DFSには、複製されたデータのコピーを異なるサーバーに保存できる組み込みの複製メカニズムが含まれています。 したがって、異なるサーバー上の複数の実リソースが1つのノードに対応できます。 スマートではなく、そのうちの1つだけを取ることは可能ですが(コードで何も変更されない場合、最後のものが取られます)、私はSambaが行う選択を使用することにしました。そのような場合、smbclientはパスを返す単一のコマンドで実行されます接続するサーバー上のリソースに。 ちなみに、Sambaはノードをランダムに選択すると思われます(コードは見えませんでしたが)。
最初のスクリプトを理解したので、2番目のスクリプトに進みましょう。 コマンドラインから(osascriptを使用して)インタラクティブに実行できるように書かれています。 実際、開始する3番目の方法があり、それについてはすぐ下にあります。
-このスクリプトは、リソースへのDFSパスを使用して、WindowsネットワークリソースをFinderに接続します。
-スクリプトは外部bashスクリプトを呼び出して、DFSパスをパスに変換します
-実際の共有リソースへ
プロパティ DFSRootServer: "dfs.mycompany" -ここにルートDFSサーバーの名前を挿入します
プロパティ BashScriptPath: "/ Users / Shared / Scripts / dfs_to_share"-bashスクリプト へのパス
プロパティ isRunFromCommandLine: true
-このハンドラーは、ThisServiceが整理に使用します
-[サービス]メニューからスクリプトを呼び出します。
-"run"メソッドからも呼び出します。 元のUNCパスが引数として渡されます。
処理中(入力)
試してみる
シェルスクリプト "/ bin / bash" & BashScriptPath & ¬ を 実行 する ように realPath を 設定 し ます
"" & DFSRootServer & "'" &入力& "'"
エラー時 errMessage 番号 errNumber
-スクリプトはさまざまな状況でさまざまなエラーコードを返します。ここで処理します
errNumber が 100の 場合
errMessage を 「スクリプトの実行中の内部エラー」に 設定し ます。
それ以外の 場合、 errNumber が 200の 場合
errMessage を 「サーバーからノードのDFSテーブルを取得できません。」に 設定 します。
アクティブなKerberosチケットがあるかどうかを確認してください。
それ以外の 場合、 errNumber が 300の 場合
errMessage を 「smbclientを使用してDFSホストを取得する際のエラー」に 設定し ます。
他に
errMessage を 「シェルスクリプトの実行中の不明なエラー:」に設定し ます ( テキスト として errNumber )
終了する 場合
isRunFromCommandLineの場合
-アプリケーションがコマンドラインから起動された場合、
-コンソールにメッセージを表示する
ログerrMessage
他に
表示ダイアログ errMessage ボタン { "閉じる" }
終了する 場合
帰る
終了する
試してみる
(* Finderに特定のパスのディレクトリを強制的に開く最も便利な方法は、
「場所を開く」方法を使用します。 デバイスを自動的にマウントし、
Finderウィンドウで必要なディレクトリを開きます。 しかし、この方法には入力が必要です
URLビューのパスなので、Pythonを使用して変換します
URL表現へのUNCパス*)
urlOfPath を 「smb:」に 設定 します ( シェルスクリプトを実行 ¬
「python -c 'import urllib、sys; print urllib.pathname2url(sys.argv [1])'」 & ¬
realPathの引用形式 )
アプリケーション 「Finder」に 通知 する
オープンロケーションurlOfPath
終わらせる
エラー時 errMessage
表示ダイアログ errMessage ボタン { CloseButton }
終了する
終了プロセス
実行時に argv
ConnectButton を Connectに 設定 し ます
CancelButton を 「キャンセル」に 設定します
-パスをパラメーターとして渡し、コマンドラインから開始されたかどうかを確認します
( count of argv ) が 0に 等しい 場合
表示ダイアログ 「UNCパスを入力してください:」 デフォルトの回答 「」 ¬
ボタン { ConnectButton、CancelButton }デフォルトボタン1
結果 を リスト として { UNC_path、button_pressed }に コピーします
button_pressed が ConnectButtonで、 UNC_path が 「」で は ない 場合
isRunFromCommandLine を falseに 設定 し ます
プロセス( UNC_path )
終了する 場合
他に
プロセス( argvのアイテム 1 )
終了する 場合
エンドラン
runメソッドは、スクリプトの実行後に自動的に呼び出されます。単一のウィンドウが表示され、ユーザーは目的のリソースへのソースパスを入力するよう求められます。 スクリプトの主な機能は、「プロセス」メソッドにあります。 サーバーへの実際のパスを入力として受け取り、上記のbashスクリプトを実行し、結果を解釈して、Finderプログラムで結果のパスを開きます。
この最後の段階で、1つの問題が発生します。 Finderには便利な[サーバーに接続]ダイアログボックスがあります。 残念ながら、この機能はAppleScriptを介して利用できないため、いくつかの異なるオプションを試した後、URLが入力されることを期待する「場所を開く」メソッドに決めました。 このため、最初のスクリプトによって返された文字列をURL表現に変換し、一部の文字をコードに置き換える必要があります。 幸いなことに、Mac OS Xには、必要なことを正確に実行する便利なメソッドを持つライブラリを備えたpythonインタープリターが付属しています。 結果のURLをFinderにフィードすると、必要なディレクトリを含むウィンドウが魔法のように開きます。
これらのスクリプトの作業を試みると、1つの機能に気づくでしょう:Finderダイアログボックスを介してリソースに接続すると、直接分割されたリソースがサーバーにマウントされ、Finderでこのリソースのディレクトリツリー全体をウォークスルーできます。 また、記述されたスクリプトの結果として、ソースパスとそのサブディレクトリで参照されているディレクトリのみが利用可能です。 誰かとして、私はこの行動がより好きです。あなたはあなたが望むものを手に入れますが、それ以上のものはありません。 さらに深くする必要があります。パスに参加してこの部分のみを接続するか、Finderウィンドウのサイドパネルで接続されたサーバーを選択し、そこから階層を下ることができます。
次に、スクリプトを実行するための3番目の約束された方法について説明します。 Cocoaプログラムでは、「サービス」メニューが利用可能であり、このメニューからスクリプトを呼び出すことができれば非常に便利です。 テキスト内のパスを選択し、このメニューからアイテムを選択(またはこのアイテムに対応する書き込みキーを押します)して、Finderでこのパスを開きます。 これを行うのは難しくないことが
わかりました。ThisServiceという無料のプログラム(ドネーションウェア)があり、スクリプトを[サービス]メニューに接続できます。 ThisServiceでは、スクリプトに入力として文字列を受け取る「プロセス」メソッドが必要であるため、スクリプトを2つのメソッドに分割したのはそのためです。 簡単なセットアップの後、うまくいきました。
Apptivateと呼ばれる別の便利なプログラムがあります。これは、システム全体のホットキーを割り当てて、スクリプトを含むアプリケーションを起動できるようにするものです。 スクリプトの起動をキーの組み合わせに添付しました。これで、いつでも画面に[サーバーに接続]ウィンドウのバージョンを取得できます。
ところで、Snow Leopardに関する重要な観察結果の1つです。 すでに有効なKerberosチケットがあり、すべてのSMBボリュームを無効にすると、チケットは失われます。 このおかしな振る舞いは、5分前にすべてがうまくいったにもかかわらず、時々ネットワークオブジェクトに接続できないことに突然気付くという事実につながります。 これは、「チケットの表示」プログラム(キーチェーンから実行可能)を開始し、ボリュームを接続および切断し、チケットに何が起こるかを見ると、はっきりと見えます。 その結果、私は常に手元に置いて、Apptivateプログラムでホットキーを使用することにしました。
結論として、説明したすべてのものはコンピューター(Mac OS X Snow Leopard、バージョン10.6.4)でのみ、ABBYYの壁内でのみテストされたことを警告する必要があります。 気付いた不正確な点についてコメントを書き、改善できる点を提案してください。 そして、私と、興味のあるすべての人は感謝するだけです。