Как изменить текущий рабочий каталог оболочки в Go? - PullRequest
0 голосов
/ 21 сентября 2018

Я хочу реализовать команду cd с помощью Go, main.go:

func main() {
    flag.Parse()
    if flag.NArg() == 0 {
        curUser, err := user.Current()
        if err != nil {
            log.Fatal(err)
        }
        os.Chdir(curUser.HomeDir)
        // or like this
        // cmd := exec.Command("cd", curUser.HomeDir)
        fmt.Println(os.Getwd())   // ok in application
    }
}

Но когда я запускаю go run main.go в оболочке, она все равно не переключается на мой домашний каталог.

Так как я могу изменить мой рабочий каталог в оболочке, запустив файлы go?

code running

1 Ответ

0 голосов
/ 21 сентября 2018

Вы не можете сделать это;каждый дочерний процесс имеет свой рабочий каталог, унаследованный от родительского процесса.В этом случае ваш cd получает свой рабочий каталог от своего родителя (вашей оболочки).Дочерний процесс не может изменить каталог - или любое другое состояние - родительского процесса.

Это базовое разделение процесса.Разрешение дочерним процессам влиять на своих родителей будет иметь всевозможные проблемы безопасности и удобства использования.

Оболочки реализуют cd как «специальную встроенную функцию».Это не внешний двоичный файл:

$ where cd
cd: shell built-in command

Другими словами, когда оболочка запускает команду cd, она запускается в том же процессе, что и остальная часть оболочки.

Основная логикаREPL оболочки выглядит примерно так:

for {
    line := waitForInputLine()
    switch {
        case strings.HasPrefix(line, "cd"):
            os.chdir(strings.Split(line, " ")[1])

        // ..check other builtins and special cases./

        default:
            runBinary(line)
    }
}

Невозможно реализовать это во внешнем двоичном файле, независимо от того, какой язык вы используете для его реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...