web-dev-qa-db-ja.com

MySQLの不適切に構成された理由:相対パスの安全でない使用

Djangoを使用しており、python manage.py runserver次のエラーが表示されます。

ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
  Referenced from: /Library/Python/2.7/site-packages/_mysql.so
  Reason: unsafe use of relative rpath libmysqlclient.18.dylib in /Library/Python/2.7/site-packages/_mysql.so with restricted binary

これを修正する方法が完全にはわかりません。 pip経由でMySQL-pythonをインストールしました。そして、私は this ステップを先に進めました。

また、これがEl Capitan Beta 3であることを指摘したいと思います。

28
nonamorando

OS X El Capitan(10.11)では、Apple added System Integrity Protection

これにより、/usrなどの保護された場所にあるプログラムが、別の共有ライブラリへの相対参照を使用する共有ライブラリを呼び出すことを防ぎます。 _mysql.soの場合、共有ライブラリlibmysqlclient.18.dylibへの相対参照が含まれます。

将来、共有ライブラリ_mysql.soが更新される可能性があります。それまでは、install_name_toolユーティリティを使用して絶対参照を使用するように強制できます。

libmysqlclient.18.dylibが/ usr/local/mysql/lib /にあると仮定して、コマンドを実行します:

Sudo install_name_tool -change libmysqlclient.18.dylib \
  /usr/local/mysql/lib/libmysqlclient.18.dylib \
  /Library/Python/2.7/site-packages/_mysql.so
76
Greg Glockner

何かのために修正する相対パスがたくさんある場合(opencvライブラリで私が起こったように)。次のスニペットを使用できます。

それに応じてABSPATHとLIBPATHSを変更します。ターミナルに貼り付けることができるrPathChangeCmd.txtを作成します。また、エラーが発生した場合にrPathChangeErr.txtを作成します。コマンドを貼り付ける前に、エラーファイル(作成されている場合)を確認することをお勧めします。

import glob
import subprocess
import os.path

ABSPATH = "/usr/local/lib/"  # absolute path to relative libraries
# libraries to correct
LIBPATHS = ['/usr/local/lib/python2.7/site-packages/cv2.so', '/usr/local/lib/libopencv*'] 

PREFIX = 'Sudo install_name_tool -change '

assert(ABSPATH.startswith('/') and ABSPATH.endswith('/'), 
    'please provide absolute library path ending with /')

libs = []
for path in LIBPATHS:
  libs += glob.glob(path)

cmd =  []
err = []
for lib in libs:
  if not os.path.isfile(lib):
    err.append(lib+" library not found") # glob should take care
  datastr = subprocess.check_output(['otool','-l','-v', lib])
  data = datastr.split('\n') 
  for line in data:
    ll = line.split()
    if not ll: continue
    if (ll[0] == 'name' and ll[1].endswith('.dylib') and not ll[1].startswith('/')):
      libname = ll[1].split('/')[-1]
      if os.path.isfile(ABSPATH+libname):  
        cmd.append(PREFIX+ll[1]+" "+ABSPATH+libname+' '+lib)
      else:
        err.append(ABSPATH+libname+" does not exist, hence can't correct: "+ll[1]+" in: "+lib)

ohandle = open("rpathChangeCmd.txt", 'w')
for lib in cmd:
  ohandle.write(lib+'\n')
ohandle.close()

if err:
  ehandle = open("rpathChangeErr.txt", 'w')
  for e in err:
    ehandle.write(e+'\n')
  ehandle.close()
0