source

작업 디렉토리를 변경하는 셸 'cd' 명령과 동등합니까?

goodcode 2022. 9. 18. 21:33
반응형

작업 디렉토리를 변경하는 셸 'cd' 명령과 동등합니까?

cd는 작업 디렉토리를 변경하기 위한 셸 명령어입니다.

Python에서 현재 작업 디렉토리를 변경하려면 어떻게 해야 합니까?

작업 디렉토리는 다음과 같이 변경할 수 있습니다.

import os

os.chdir(path)

이 방법을 사용할 때 따라야 할 두 가지 모범 사례가 있습니다.

  1. 잘못된 경로에서 예외(WindowsError, OSError)를 포착합니다.예외가 발생하면 재귀 작업, 특히 파괴 작업을 수행하지 마십시오.그들은 새로운 경로가 아닌 오래된 경로로 운영될 것이다.
  2. 작업을 마치면 이전 디렉토리로 돌아갑니다.이것은 예외적으로 안전한 방법으로 chdir 콜을 Brian M과 같은 컨텍스트 매니저로 랩함으로써 실행할 수 있습니다.헌트는 대답에서 그랬다.

하위 프로세스의 현재 작업 디렉토리를 변경해도 상위 프로세스의 현재 작업 디렉토리는 변경되지 않습니다.이것은 Python 인터프리터에도 해당됩니다.사용할 수 없습니다.os.chdir()콜 프로세스의 CWD를 변경합니다.

다음은 작업 디렉토리를 변경하는 컨텍스트 관리자의 예입니다.이것은 다른 곳에서 참조되는 ActiveState 버전보다 단순하지만 작업을 수행할 수 있습니다.

콘텍스트 매니저:cd

import os

class cd:
    """Context manager for changing the current working directory"""
    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)

또는 ContextManager를 사용하여 보다 간결한 동등한 것(아래)을 사용해 보십시오.

import subprocess # just to call an arbitrary command e.g. 'ls'

# enter the directory like this:
with cd("~/Library"):
   # we are in ~/Library
   subprocess.call("ls")

# outside the context manager we are back wherever we started.

나는 사용할 것이다.os.chdir다음과 같습니다.

os.chdir("/path/to/change/to")

참고로 현재 경로를 파악하려면os.getcwd().

자세한 것은 이쪽

cd()제너레이터와 데코레이터를 사용하여 쓰기 쉽습니다.

from contextlib import contextmanager
import os

@contextmanager
def cd(newdir):
    prevdir = os.getcwd()
    os.chdir(os.path.expanduser(newdir))
    try:
        yield
    finally:
        os.chdir(prevdir)

그 후, 디렉토리는 예외가 발생해도 되돌립니다.

os.chdir('/home')

with cd('/tmp'):
    # ...
    raise Exception("There's no place like /home.")
# Directory is now back to '/home'.

비교적 새로운 버전의 Python을 사용하는 경우 다음과 같은 컨텍스트 매니저를 사용할 수도 있습니다.

from __future__ import with_statement
from grizzled.os import working_directory

with working_directory(path_to_directory):
    # code in here occurs within the directory

# code here is in the original directory

갱신하다

직접 롤링을 원하는 경우:

import os
from contextlib import contextmanager

@contextmanager
def working_directory(directory):
    owd = os.getcwd()
    try:
        os.chdir(directory)
        yield directory
    finally:
        os.chdir(owd)

이미 지적된 바와 같이 위의 모든 솔루션은 현재 프로세스의 작업 디렉토리만 변경합니다.이것은 Unix 쉘로 돌아가면 없어집니다.긴급한 경우에는 다음과 같은 끔찍한 해킹으로 Unix의 부모 셸 디렉토리를 변경할 수 있습니다.

def quote_against_shell_expansion(s):
    import pipes
    return pipes.quote(s)

def put_text_back_into_terminal_input_buffer(text):
    # use of this means that it only works in an interactive session
    # (and if the user types while it runs they could insert characters between the characters in 'text'!)
    import fcntl, termios
    for c in text:
        fcntl.ioctl(1, termios.TIOCSTI, c)

def change_parent_process_directory(dest):
    # the horror
    put_text_back_into_terminal_input_buffer("cd "+quote_against_shell_expansion(dest)+"\n")

os.chdir()옳은 길입니다.

os.chdir()의 피톤어 버전입니다.cd.

import os

abs_path = 'C://a/b/c'
rel_path = './folder'

os.chdir(abs_path)
os.chdir(rel_path)

os.chdir(abs_path) 또는 os.chdir(rel_path) 모두 사용할 수 있습니다.상대 경로를 사용하기 위해 os.getcwd()를 호출할 필요는 없습니다.

Brian이 지적하고 sh(1.0.8+)에 근거한 방향성

from sh import cd, ls

cd('/tmp')
print ls()

'cd' 같은 걸 하고 싶다면" 옵션, 입력:

os.chdirls..")

Windows cmd: cd..와 동일합니다.물론 Import os는 필수입니다(예를 들어 코드 첫 번째 줄에 입력합니다).

Path패스 라이브러리의 오브젝트는 컨텍스트 매니저와chdir위한 : " " " 입니다.

from path import Path

with Path("somewhere"):
    ...

Path("somewhere").chdir()

spyder와 love GUI를 사용하는 경우 화면 오른쪽 상단 모서리에 있는 폴더 버튼을 클릭하기만 하면 현재 디렉토리로 원하는 폴더/디렉토리를 탐색할 수 있습니다.그런 다음 Spyder IDE에서 창의 파일 탐색기 탭으로 이동하여 거기에 있는 모든 파일/폴더를 볼 수 있습니다. 현재 작업 디렉토리를 확인하려면 Spyder IDE의 콘솔에 가서 간단히 입력하십시오.

pwd

이전에 선택한 경로와 동일한 경로를 인쇄합니다.

스크립트 프로세스의 현재 디렉토리를 변경하는 것은 간단한 일입니다.문제는 python 스크립트가 호출되는 명령어창의 현재 디렉토리를 어떻게 변경할 것인가 하는 것입니다.이것은 매우 어려운 일입니다.Windows의 Bat 스크립트 또는 Bash 쉘의 Bash 스크립트는 셸 자체가 인터프리터이기 때문에 일반 cd 명령어를 사용하여 이를 수행할 수 있습니다.Windows와 Linux 모두에서 Python은 프로그램이며 어떤 프로그램도 부모의 환경을 직접 변경할 수 없습니다.그러나 간단한 셸 스크립트와 대부분의 하드 작업을 수행하는 파이썬 스크립트를 조합하면 원하는 결과를 얻을 수 있습니다.예를 들어 이전/앞으로/선택 재방문 시 트래버설 이력을 가진 확장 cd 명령어를 만들기 위해 간단한 bat 스크립트에 의해 호출되는 비교적 복잡한 Python 스크립트를 작성했습니다.트래버설 리스트는 파일에 보존되어 타겟디렉토리가 첫 번째 행에 표시됩니다.python 스크립트가 반환되면 bat 스크립트는 파일의 첫 번째 행을 읽고 그것을 cd의 인수로 만듭니다.완전한 bat 스크립트(간단한 코멘트 제외)는 다음과 같습니다.

if _%1 == _. goto cdDone
if _%1 == _? goto help
if /i _%1 NEQ _-H goto doCd
:help
echo d.bat and dSup.py 2016.03.05. Extended chdir.
echo -C = clear traversal list.
echo -B or nothing = backward (to previous dir).
echo -F or - = forward (to next dir).
echo -R = remove current from list and return to previous.
echo -S = select from list.
echo -H, -h, ? = help.
echo . = make window title current directory.
echo Anything else = target directory.
goto done

:doCd
%~dp0dSup.py %1
for /F %%d in ( %~dp0dSupList ) do (
    cd %%d
    if errorlevel 1 ( %~dp0dSup.py -R )
    goto cdDone
)
:cdDone
title %CD%
:done

python 스크립트(dSup.py는 다음과 같습니다.

import sys, os, msvcrt

def indexNoCase ( slist, s ) :
    for idx in range( len( slist )) :
        if slist[idx].upper() == s.upper() :
            return idx
    raise ValueError

# .........main process ...................
if len( sys.argv ) < 2 :
    cmd = 1 # No argument defaults to -B, the most common operation
elif sys.argv[1][0] == '-':
    if len(sys.argv[1]) == 1 :
        cmd = 2 # '-' alone defaults to -F, second most common operation.
    else :
        cmd = 'CBFRS'.find( sys.argv[1][1:2].upper())
else :
    cmd = -1
    dir = os.path.abspath( sys.argv[1] ) + '\n'

# cmd is -1 = path, 0 = C, 1 = B, 2 = F, 3 = R, 4 = S

fo = open( os.path.dirname( sys.argv[0] ) + '\\dSupList', mode = 'a+t' )
fo.seek( 0 )
dlist = fo.readlines( -1 )
if len( dlist ) == 0 :
    dlist.append( os.getcwd() + '\n' ) # Prime new directory list with current.

if cmd == 1 : # B: move backward, i.e. to previous
    target = dlist.pop(0)
    dlist.append( target )
elif cmd == 2 : # F: move forward, i.e. to next
    target = dlist.pop( len( dlist ) - 1 )
    dlist.insert( 0, target )
elif cmd == 3 : # R: remove current from list. This forces cd to previous, a
                # desireable side-effect
    dlist.pop( 0 )
elif cmd == 4 : # S: select from list
# The current directory (dlist[0]) is included essentially as ESC.
    for idx in range( len( dlist )) :
        print( '(' + str( idx ) + ')', dlist[ idx ][:-1])
    while True :
        inp = msvcrt.getche()
        if inp.isdigit() :
            inp = int( inp )
            if inp < len( dlist ) :
                print( '' ) # Print the newline we didn't get from getche.
                break
        print( ' is out of range' )
# Select 0 means the current directory and the list is not changed. Otherwise
# the selected directory is moved to the top of the list. This can be done by
# either rotating the whole list until the selection is at the head or pop it
# and insert it to 0. It isn't obvious which would be better for the user but
# since pop-insert is simpler, it is used.
    if inp > 0 :
        dlist.insert( 0, dlist.pop( inp ))

elif cmd == -1 : # -1: dir is the requested new directory.
# If it is already in the list then remove it before inserting it at the head.
# This takes care of both the common case of it having been recently visited
# and the less common case of user mistakenly requesting current, in which
# case it is already at the head. Deleting and putting it back is a trivial
# inefficiency.
    try:
        dlist.pop( indexNoCase( dlist, dir ))
    except ValueError :
        pass
    dlist = dlist[:9] # Control list length by removing older dirs (should be
                      # no more than one).
    dlist.insert( 0, dir ) 

fo.truncate( 0 )
if cmd != 0 : # C: clear the list
    fo.writelines( dlist )

fo.close()
exit(0)

언급URL : https://stackoverflow.com/questions/431684/equivalent-of-shell-cd-command-to-change-the-working-directory

반응형