You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨平台CLI工具my-command的目录存储实现方案问询

Great question! Building cross-platform CLI tools that persist user data can feel a bit tricky at first, but there’s a straightforward, standard approach that works seamlessly across Linux, macOS, and Windows. Let’s break this down step by step.

Core Idea

Forget using environment variables—they’re session-specific (disappear when the terminal closes unless users manually add them to their shell config, which is a hassle). Instead, we’ll store the parked directory in a platform-standard user config folder. Every OS has a dedicated, persistent location for app settings, and we can auto-detect that path to keep things consistent.

Step-by-Step Implementation

1. Identify Cross-Platform Config Paths

Each OS follows a standard for where apps should store config data:

  • Linux: Follows the XDG Base Directory spec—use $XDG_CONFIG_HOME if set, otherwise default to ~/.config
  • macOS: Native convention is ~/Library/Application Support (you can also support XDG for consistency, but the native path feels more familiar to macOS users)
  • Windows: Uses %APPDATA% (usually resolves to C:\Users\<YourUsername>\AppData\Roaming)

Your CLI can use language-specific utilities to fetch this path automatically (no hardcoding paths!).

2. Build the park Command

When a user runs my-command park:

  1. Grab the current working directory (CWD)
  2. Create the config folder if it doesn’t exist (recursively, so parent folders are created too)
  3. Write the CWD to a simple file in that config folder (e.g., parked_dir.txt—plain text is fine for this use case, or JSON if you want to expand later)

3. Build the show-dir Command

When a user runs my-command show-dir:

  1. Check for the parked directory file in the config folder
  2. If it exists, read and print the stored path
  3. If it doesn’t exist, show a friendly error telling the user to run park first
Example Code (Node.js)

Here’s a simplified working example using Node.js (it uses only built-in modules, no external dependencies):

const os = require('os');
const path = require('path');
const fs = require('fs').promises;

// Get the OS-specific config directory for our CLI
function getConfigDir() {
  switch (process.platform) {
    case 'win32':
      return path.join(os.homedir(), 'AppData', 'Roaming', 'my-command');
    case 'darwin':
      return path.join(os.homedir(), 'Library', 'Application Support', 'my-command');
    case 'linux':
      const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
      return path.join(xdgConfig, 'my-command');
    default:
      throw new Error(`Unsupported platform: ${process.platform}`);
  }
}

// Handle the `park` command
async function handlePark() {
  const currentDir = process.cwd();
  const configDir = getConfigDir();

  // Create config directory if it doesn't exist
  await fs.mkdir(configDir, { recursive: true });

  const parkedFile = path.join(configDir, 'parked_dir.txt');
  await fs.writeFile(parkedFile, currentDir, 'utf8');

  console.log(`Successfully parked directory: ${currentDir}`);
}

// Handle the `show-dir` command
async function handleShowDir() {
  const configDir = getConfigDir();
  const parkedFile = path.join(configDir, 'parked_dir.txt');

  try {
    const parkedDir = await fs.readFile(parkedFile, 'utf8');
    console.log(parkedDir.trim());
  } catch (err) {
    if (err.code === 'ENOENT') {
      console.error('No directory has been parked yet! Run `my-command park` first.');
    } else {
      console.error('Failed to read parked directory:', err.message);
    }
  }
}

// Parse command-line arguments and run the right command
async function main() {
  const [command] = process.argv.slice(2);

  switch (command) {
    case 'park':
      await handlePark();
      break;
    case 'show-dir':
      await handleShowDir();
      break;
    default:
      console.error(`Unknown command: ${command}`);
      console.log('Available commands: park, show-dir');
  }
}

main().catch(err => console.error(err));
Notes for Other Languages
  • Python: Use the appdirs library (pip install appdirs) to fetch the config path, os.getcwd() to get the current directory, and standard file I/O to read/write the path.
  • Go: Use os.UserConfigDir() to get the standard config path, os.Getwd() for the current directory, and os.Create()/os.ReadFile() for file operations.
Why Not Environment Variables?

As mentioned earlier, env vars are temporary—they only last for the current terminal session. Storing the path in a config file keeps it persistent across reboots and terminal sessions without requiring users to modify their shell config files (like .bashrc or .zshrc), which is a much better user experience.

Pro Tips
  • Always handle file I/O errors (e.g., permission issues, full disk) to avoid crashes.
  • If you plan to expand your CLI later, consider using JSON instead of plain text to store multiple values (like multiple parked directories).
  • Test on all three target platforms to ensure the config path detection works as expected.

内容的提问来源于stack exchange,提问作者ajthinking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:44:31