强制“git status”在终端上输出颜色(在脚本中)

时间:2013-04-18 02:52:04

标签: git shell unix io terminal

编辑:

我想建议解析颜色是一个普遍错误的想法。

我想要它的部分原因是我可以解析它并在我自己的脚本输出中传递它。这是......好吧,但是使用瓷器或其他一些东西可能会更加巧妙,并且自己重新制作彩色部件!

原始答案如下。


我喜欢看颜色,因为我的脚本足够强大(到目前为止)处理颜色代码。看起来我确实反对这里,但老实说,我不知道在脚本中解析转义代码之类的东西是多么重要。如果颜色有助于交互式使用,为什么它们不会帮助我使用脚本,我可能会聚合数据并处理比我手动更多的数据?颜色不是更重要吗?

无论如何,我有一个简洁的小shell脚本,我写了munges git status输出,我只是想让这个脚本保持颜色完整。我的全局git配置已设置,以便更改和未跟踪文件的列表在git状态中显示为彩色。不幸的是,与git diff不同的是,我找不到git status强制颜色的选项。

非常清楚,这就是问题:

$ git status

产生完美的输出,但(摘自我的脚本)

git status | sed "s/^#/\x1b[34m#[0m/"

不会产生彩色git status输出,你甚至可以在这里看到我明确地将前导哈希字符转换为蓝色,因为它有助于突出显示我脚本输出的不同区域。

有谁知道如何让它推出颜色?是否有可以使用的标准程序可以用作“假终端”STDIN / STDOUT管道?我实际上也在研究一个pty伪终端工具,所以我当然可以为此目的使用它,但它是一个相当苛刻的解决方案(并没有准备好使用,因为我还没有完成构建它)。

3 个答案:

答案 0 :(得分:76)

为了避免更改你的git配置,你可以通过使用-c传递config变量来为当前命令执行此操作:

    git -c color.status=always status | less -REX

该变量仅适用于 status 命令。对于 diff show log ,变量为color.ui

    git -c color.ui=always diff | less -REX

请注意,-c必须在statusdiff参数之前变为,而不是之后。

答案 1 :(得分:20)

编辑:

我想强烈建议解析颜色是一个普遍错误的想法。

我想要它的部分原因是我可以解析它并在我自己的脚本输出中传递它。这是......好吧,但是使用瓷器或其他一些东西可能会更加巧妙,并且自己重新制作彩色部件!

原始答案如下。


在提问之后,我一直很快找到答案。与思考问题的时间有关,可以写出来,制定更好的方法来解决问题。无论如何,解决方案只是

git config color.status always

我认为通用解决方案涉及expect或与pty相关的强制任何需要它的程序认为它们在终端上。

答案 2 :(得分:2)

使用执行shell命令的git别名时遇到了同样的问题。显然git shell不会从当前环境继承,所以它对我的着色设置一无所知。

除了添加全局git color ui设置之外,我通过使我的别名看起来如下所示来修复此问题,它是需要被告知使用颜色的辅助命令,因为git将默认为1.8.x版本的人已经提到了。

#include <boost/asio.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
#include <boost/thread.hpp>

struct Task {
    virtual ~Task() = default;
    virtual int  Execute()           const = 0;
    virtual bool IsShutdownRequest() const { return false; }
};

struct TimeSeriesTask : Task {
    TimeSeriesTask(int id) : _id(id) {}
    virtual int  Execute()           const { return _id;   }

  private:
    int _id;
};

struct ShutdownTask : Task {
    virtual int  Execute()           const { return 0;    }
    virtual bool IsShutdownRequest() const { return true; }
};

class Manager {
  public:
    Manager() : _running(false)
    { }

    void Start() {
        boost::lock_guard<boost::mutex> lk(_stateMutex);
        if (!_running) {
            _running = true;
            _workerThread = boost::thread(&Manager::workerMain, this);
        }
    }

    void workerMain() {
        while(_running) {
            queue.consume_one([this](std::shared_ptr<Task> task) {
                if (task->IsShutdownRequest()) {
                    _running = false;
                } else {
                    int result = task->Execute();
                    processResult(result);
                }
            });
        };
    }

    void processResult(unsigned int x) {
        int result = x - 1;
        std::cout << "Processing result = " << result << " on thread " << boost::this_thread::get_id() << std::endl;
    }

    void QueueData(int x) {
       if (x > 0)
            queue.push(std::make_shared<TimeSeriesTask>(x));
        else
            queue.push(std::make_shared<ShutdownTask>());
    }

    void Cleanup() {
        if (_workerThread.joinable())
            _workerThread.join();
    }

  private:
    boost::mutex _stateMutex;
    boost::atomic_bool _running;
    boost::lockfree::spsc_queue<std::shared_ptr<Task>, boost::lockfree::capacity<1024> > queue;
    boost::thread _workerThread;
};

int main()
{
    Manager mgr;
    mgr.Start();

    mgr.QueueData(1);
    mgr.QueueData(2);
    mgr.QueueData(3);

    mgr.QueueData(-1);
    mgr.Cleanup();
}

现在作为别名运行时产生等效的彩色输出,就像我刚运行命令一样。

对于sed,这个其他答案似乎更可靠,使用tput。 https://unix.stackexchange.com/a/45954