問題解決 child_process execSync /bin/sh: pnpm: command not found

分享
問題解決 child_process execSync /bin/sh: pnpm: command not found
Photo by Towfiqu barbhuiya / Unsplash

Context

我在執行 child_process.execSync 時,使用了下方程式碼去跑 db migration 並且指定了環境變數 DATABASE_URL 去執行 schema refresh & seed

execSync('pnpm -F backend db:reset && pnpm -F backend seed', {
    env: { DATABASE_URL: databaseUrl },
})

本人是使用 Windows 作業系統,這行指令在我電腦中執行的很順暢,所以就開開心心的把這行程式推上 Github 了。

不料沒多久,一位使用 Mac 的同事就對我說這行程式沒辦法跑啊,一直寫說 pnpm command not found

我循思這不太可能啊,每個人都有裝了 pnpm 才對,為何這時候又冒出了這個錯誤?不會又是 Mac 的鍋吧...😂

source: https://www.igtsolutions.com/information-technology/breaking-down-barriers-navigating-the-tester-vs-developer-dynamics/

Problem

我不斷地在網路上衝浪,直到找到這篇 Stack Overflow,裡面有一段程式碼可以幫助我們 debug

const { execSync } = require('child_process')
console.log(process.env.ComSpec);// verify what terminal is used

try {
    // success command
    const resNpmVersion = execSync("npm -v");
    console.log("success", resNpmVersion.toString());

    // failed command, the result is printed in the catch block
    const resHelp = execSync("HELP");
} catch (error) {
    console.log(error.message);
    console.log("error", error.stdout.toString());
}

於是我把這段程式碼交給他,說道你把 npm 改成 pnpm 看看能不能執行?

過了一段時間後,他說:可以耶!我的版本是 9.x.x ...

我驚訝到,為什麼這樣可以執行??

Solution

於是我看了一下差異問道

是不是指定環境變數的問題呢?把 process.env 也放進去會如何呢?
execSync('pnpm -F backend db:reset && pnpm -F backend seed', {
    env: { ...process.env, DATABASE_URL: databaseUrl },
})

it's works!果真就能夠執行了!

後來找到了一篇文章 使用child_process时注意环境变量 寫道:

呼叫 child_process.execSync時,若指定了env,切記一定要把繼承來的process.env帶上。 否則最重要的PATH環境變數就可能這麼被忽略了,導致子 Process 要呼叫 shell 指令時,發生各種找不到命令的奇怪錯誤。

官方文件中也寫道:

The command lookup is performed using the options.env.PATH environment variable if env is in the options object. Otherwise, process.env.PATH is used. If options.env is set without PATH, lookup on Unix is performed on a default search path search of /usr/bin:/bin (see your operating system's manual for execvpe/execvp), on Windows the current processes environment variable PATH is used. On Windows, environment variables are case-insensitive. Node.js lexicographically sorts the env keys and uses the first one that case-insensitively matches. Only first (in lexicographic order) entry will be passed to the subprocess. This might lead to issues on Windows when passing objects to the env option that have multiple variants of the same key, such as PATH and Path.

下參數之前要先讀 spec 啊...

Read more

Windows Sandbox 沙箱閃退顯示連線已中斷解決方法

Windows Sandbox 沙箱閃退顯示連線已中斷解決方法

想拿 Windows Sandbox 測試東西,隔離環境用完就丟最省事。結果一打開沙箱就直接跳「與 Windows 沙盒環境的連線已中斷。是否要重新連線?」,訊息一出來就閃退,連畫面都還沒進去。 翻到 Eleven Forum 這串,有大神直接講解怎麼解決:把 vGPU 共用關掉。 Just had this issue after using Sandbox for years. My fix, as found in an Arabic YouTube video, is to use gpedit.msc and change the Computer Configuration -> Administrative

By GXiang
關於 Firefox 複製網址列連結貼上文本編輯器沒有網頁 Title 的解決方法

關於 Firefox 複製網址列連結貼上文本編輯器沒有網頁 Title 的解決方法

最近從 Edge 換回 Firefox,用沒幾天就被一個小地方卡住。 在 Edge 上,網址列複製網址、到 AFFiNE 筆記裡貼上,出來的是一條帶網頁標題的超連結,標題直接寫在筆記裡,之後回頭看一眼就知道那是什麼。Firefox 沒有這個行為,貼上去就是一長串網址: 筆記一多,這些網址就是一坨要一條條點開才知道是什麼的東西,關鍵字也搜不到。 先去看官方有沒有打算做。Mozilla Connect 上有這則提案:When copy / pasting URL include Meta Title of the ... - Mozilla Connect,截至寫這篇為止沒看到後續進度。 那就找插件。試了兩個: URL2Clipboard 功能最接近我要的,而且它有個細節做得很好:Ctrl + V 貼出來是帶超連結的標題,Ctrl + Shift + V(貼上為純文字)則只有標題文字,

By GXiang
UV python 操作筆記

UV python 操作筆記

前陣子看到了 uv 這個 python 套件、專案管理器,使用了之後發現簡直快、輕便又好上手,下方是我常使用的指令集 (持續更新中): 查看 python 版本清單 uv python list 💡已安裝的旁邊會顯示 python 安裝目錄位址 安裝 python 版本 # latest uv python install # specific version uv python install <version number> 初始化 uv 專案資料夾。 uv init <project name> 💡新專案預設會自動產生 git repository、.python-version、pyproject.

By GXiang
ts-rest 的 API 測試手法(1)

ts-rest 的 API 測試手法(1)

今天與朋友討論到 ts-rest 撰寫 API test 的時候可以用 Zod 的 safeParse().success 判斷 API Response 的 schema 正不正確。 Sample Code: const { body, status } = client.users.create({ body: createUserPayload(), }) expect( userContract.create.responses[201].safeParse(body) .success, ).toBe(true) 這樣做確實會減少許多傳統需要手動添加 expect.any(Type)...等等的型別驗證,如果只是單純驗證型別,確實透過 ts-rest 合約搭配的 Zod 的 safeParse

By GXiang