Изменить каталог родительской оболочки с Go - PullRequest
0 голосов
/ 31 декабря 2018

Как мне написать программу на Go, которая будет вести себя так же, как 'cd'?

Я пытался запустить команду, но она не сработала.

func main() {
    cmd := exec.Command("cd", "/media/")
    err := cmd.Run()
    log.Printf("Command finished with error: %v", err)
}

1 Ответ

0 голосов
/ 31 декабря 2018

Как я могу написать программу Go, которая будет вести себя как 'cd'?

Это невозможно в системах POSIX (даже с использованием любых других языков программирования).

Поскольку каждый процесс , включая родительский процесс оболочки, имеет свой собственный текущий рабочий каталог .Следовательно, cd должен быть встроенной оболочкой (вызывая системный вызов chdir (2) , выполняемый самим процессом оболочки), он не может быть выполнен некоторым исполняемым файлом 1023 *, потому что оболочка разветвляет новый процесс для запуска каждой команды (с использованием некоторого исполняемого файла, т.е. который не является встроенным).

Прочитайте хорошую книгу по программированию для Unix или Linux, такую ​​как ALP , для объяснения.И хорошая книга по Операционным системам , таким как Операционные системы: три простых части объяснит вам, почему это так (и не может быть разумно иначе, в POSIX-подобные или Unix-подобные системы).

Ваш код разветвляет cmd.Run) новым процессом и , что дочерний процесс * только 1041 меняет свой рабочий каталог.См. Также fork (2) & execve (2) & path_resolution (7) .

Для вызова chdir (2) системный вызов в вашем коде Go, используйте os.Chdir.Это повлияет только на ваш процесс (и все будущие дочерние процессы, созданные fork (2) , которые наследуют рабочий каталог своего родительского процесса) и, конечно, не изменит рабочий каталог вашего родительского процесса (который часто является вашей оболочкой).

Чтобы получить текущий рабочий каталог (с системным вызовом getcwd (2) ) вашего текущего процесса, используйте os.Getwd в своем коде Go (и посмотрите this ).

В Linux вы можете использовать /proc/ (подробности см. proc (5) ) для запроса рабочего каталога других процессов.Например, запустите ls -l /proc/$$/cwd в вашей оболочке.В коде Go вы будете использовать os.Readlink по пути, подобному /proc/1234/cwd и т. Д. Конечно, вы не можете изменить рабочий каталог какого-либо другого процесса (единственный рабочий каталог, который вам разрешено изменять, этоодин из ваших собственных процессов, используя chdir (2) )

Как прокомментировал Дэвид Будсворт , вы могли бы принять странное соглашение , которое:1. Ваша программа prog записывает допустимый (и соответствующий кавычки для оболочки) путь к каталогу в стандартный вывод и ничего больше.2. Вы всегда используете эту prog программу с подстановкой команды , что-то вроде cd $(prog args...) (которая может стать телом функции оболочки или псевдоним и т. Д.), Тогда ваша оболочка (не ваша prog) изменит каталог как вывод вашей программы.

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