亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么我的程序返回錯誤,指出文件不存在?

為什么我的程序返回錯誤,指出文件不存在?

Go
人到中年有點甜 2022-09-19 21:16:47
我正在編寫自定義計劃工具的基礎知識,該工具將讀取“作業”的配置文件,并將它們添加到計劃中以定期運行。它現在是非常基本的,比如重構之前的概念證明和一些其他更高級的功能。當我嘗試運行此程序時,它報告找不到該腳本。腳本“test1.sh”確實存在于我嘗試從中運行它的路徑中,并且它具有執行權限。我收到以下錯誤,但無法解釋它或解決它,因為腳本確實存在于我運行它的路徑中:-> ./scheduler-example2021/08/16 12:48:54 fork/exec /Users/me/scheduler-example/scripts/test1.sh: no such file or directory調度程序代碼:package mainimport (    "io"    "log"    "os"    "os/exec"    "path/filepath"    "time"    "github.com/go-co-op/gocron"    "gopkg.in/yaml.v3")type Config struct {    GlobalLog string `yaml:"GlobalLog"`    Jobs      []Job  `yaml:"Jobs"`}type Job struct {    Name      string `yaml:"Name"`    Command   string `yaml:"Command"`    Frequency string `yaml:"Frequency"`    Tag       string `yaml:"Tag,omitempty"`    Log       string `yaml:"Log,omitempty"`}const ROOT string = "/Users/me/scheduler-example"func main() {    // STEP1: Parse the config file    configFile := filepath.Join(ROOT, "config", "scheduler-example.yaml")    f, err := os.Open(configFile)    if err != nil {        log.Fatalln(err)    }    configData, err := io.ReadAll(f)    if err != nil {        log.Fatalln(err)    }    c := Config{}    err = yaml.Unmarshal(configData, &c)    if err != nil {        log.Fatalln(err)    }    // STEP2: Validate the config    if c.GlobalLog == "" {        log.Fatalln("Global log not defined")    }    if c.Jobs == nil {        log.Fatalln("No jobs defined")    }    for _, j := range c.Jobs {        if j.Name == "" {            log.Fatalln("Job name not defined")        }        if j.Command == "" {            log.Fatalln("Job command not defined")        }        if j.Frequency == "" {            log.Fatalln("Job frequency not defined")        }    }
查看完整描述

2 回答

?
手掌心

TA貢獻1942條經驗 獲得超3個贊

根據 Go 文檔

包執行運行外部命令。它包裝操作系統。啟動過程,以便更輕松地重新映射 stdin 和標準輸出、使用管道連接 I/O 以及執行其他調整。

它將啟動一個隔離的操作系統進程。你需要的是一個終端會話或一個直接的bash呼叫。

在 Linux 中,當你稱呼它時,實際上意味著 . 之所以有效,是因為終端(或WINDOWS上.bat文件的CMD)將文件逐行視為純bash命令。因此,要運行用戶定義的bash文件,我們可以使用./script.sh/bin/sh  script.sh./script.sh

cmd := exec.Command("/bin/sh",script)

cmd := exec.Command("bash",script)

更新:如果這種方法對您有用,請閱讀torek的answare以了解為什么這有效。

實際上,我所說的“./script.py 蜂鳴的抨擊./script.sh 是”并不是安靜的。


查看完整回答
反對 回復 2022-09-19
?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

以下是對OZahed答案的一個小小的技術更正,與Go語言并不真正相關,但對于了解您是否在Linux和Unix系統上編寫代碼很有用。

在 Linux 中,當你稱呼它時,實際上意味著 ../script.sh/bin/sh script.sh

并不完全正確。

在類Unix系統上,當你坐在終端提示符(或者或者你設置了提示符的任何東西)時——很多人使用魔術提示器,以便他們獲得他們當前的工作目錄,也許還有一些Git存儲庫信息或其他有用的項目),你會輸入一個命令::$>%

$ cmd arg1 arg2

例如。您正在使用的 shell —, , , , , ,等 - 負責分解輸入的行并嘗試運行一個或多個進程。通常,他們會將其分解為 、等。如果其中一些單詞包含 shell 元字符(、等),它們將對這些元字符執行自己的特殊操作。這些可能會變得非常復雜,但它們都取決于該特定的 shell:中使用的語法與 中的語法不同,例如,在許多重要方面。/bin/sh/bin/bash/usr/local/bin/bashdashtcshfishcmdarg1*$bashtcsh

無論如何,一旦這個 shell 已經過了拆分參數并準備好調用將在 Go 中使用的相同系統調用的點,則 shell 通常會調用 ,通常在使用 或 變量搜索第一個或最佳可執行文件之后(再次以 shell 相關的方式)。此系統調用:execveexec.Cmdexecve$path$PATHexecve

  • 要求提供的路徑名為文件;

  • 要求使用執行權限標記命名文件;和

  • 要求命名文件包含操作系統本身認為可執行的數據

如果這三個測試中的任何一個失敗,系統調用本身將失敗。execve

正是在這一點上,Go和外殼往往會急劇分化。如果文件存在并標記為可執行文件,但失敗,則 shell 通常會執行以下一項或兩項操作:exec.Cmdexecve

  • 打開并讀?。赡苤皇俏募囊徊糠郑試L試猜測哪個shell(如果有的話)可以運行此文件,然后

  • 對該文件運行該外殼程序或某個默認外殼程序。

例如,這是導致 的最后一步。如果腳本看起來像是腳本,則 shell(即使是 ) 也應使用 。如果腳本看起來像是腳本,則 shell 應找到該程序并使用作為參數運行該程序。/bin/sh ./script.sh/bin/shtcsh/bin/sh ./scriptbashbash./script.sh

了解可執行腳本的關鍵技巧:#!

請注意,上述要求我們從操作系統級系統調用中獲取錯誤。在任何現代Unix系統上,我們都可以通過用一條特殊的行開始我們的腳本避免這個錯誤。此特殊行采用兩個字符的形式,后跟可選的空格,后跟解釋器程序的路徑名,后跟更多可選的空格,以及一個或多個參數(具體取決于特定操作系統)。execve#!

也就是說,如果我們將 shell 腳本編寫為:

#! /bin/sh
echo this was run by /bin/sh

并使其可執行,應用于此腳本的系統調用,就好像它是一個系統調用,后跟此腳本的路徑名。因此,如果我們使用的路徑名是 ,我們會得到運行的效果。execveexecve/bin/sh./script/bin/sh ./script

該部分來自腳本,因此我們可以控制解釋器的確切路徑。例如,如果我們編寫一個 awk 腳本,并且如果解釋器位于 中,則:/bin/shawk/usr/bin/awk

#! /usr/bin/awk

是正確的第一行。

有趣的是,這使我們能夠編寫一個自我刪除的腳本:

#! /bin/rm

運行時,此腳本將自行刪除。(文件的其余部分(如果有)無關緊要:該命令只是刪除命名文件。使用 作為解釋器生成自重命名腳本。/bin/rm/bin/mv

由于某些系統和其他系統上的程序,如今的一個常見技巧是使用POSIX命令來查找解釋器的二進制文件:python/usr/bin/usr/local/binenv

#! /usr/bin/env python

調用。該命令用于查找命令,然后調用(系統調用的 C 庫包裝器)或任何合適的內容。如果一個系統同時安裝了 python2 和 python3,并且調用了特定的變體,則確保我們找到一個 python3 解釋器,而不是一個 python2 解釋器。/usr/bin/env python ./script.pyenv$PATHpythonexeclexecve/usr/local/bin/python ./script.pypython2python3#! /usr/bin/env python3

如果你用適當的臺詞來寫你的劇本,你永遠不會問到導致這些答案的問題。:-)#!


查看完整回答
反對 回復 2022-09-19
  • 2 回答
  • 0 關注
  • 100 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號