Windows10以后

Windows 10

  • 这是一个很符合当下审美的版本,当然蓝屏问题真是药丸吃太多。
  • 抛开蓝屏不说,其他各方面都让我感觉直追MacBook,特别是在最新版 MacBook 出来以后,更加认可我这个观点,日后还要不要入手Mac,有待考虑,那个Touch Bar纯粹是个没用的东西,竟然把我的Esc键给搞掉了!
  • 现在的我,对自己的机器还是挺满意的,完美的 ThinkPad,小机械加触控板,在使用的时候,已经三年没有碰鼠标了,当然玩游戏的时候用了三四回。
  • 换了内存,加了固态感觉自己飞起来了,但是和Mac的PCIe接口的固态比起来,还是差了几个档次,这是最大的痛点之一

    • Bash On Windows 是微软统治全宇宙里一个插曲,但是对于我们来说意义很明显
  • 但是,事实真是如此吗?

开启 Bash On Windows

  1. 首先确保你的系统版本是大于14393.0, 那么在系统设置里面(Win + I)->更新和安全->针对开发人人员->开发人员模式
  2. 摁下Win键,打开开始菜单栏,直接输入 启用或关闭 Windows 功能,打开后,翻到最下面,勾选适用于 Linux 的 Windows子系统(Beta),就能开启这个东西。
  3. 重启后,打开cmd 或者 PowerShell 输入 bash 回车,就能看见这个子系统开始下载了,等下载完成可能需要重启,再重来一遍操作,就行了!

    缺点

  4. PowerShell ISE 无法进入这个子系统

  5. 由于不能用ISE,所以字体很难看,背景也不好调整,故相当于废了一半。
  6. 功能不完善,或者说被阉割了。

举个栗子

  • Windows 10出了一个新功能,叫做 聚焦(Windows spotlight),几乎收到了一致好评,那么如何将这些在聚焦里的照片搞出来呢?
  • 经过查阅会发现,这个聚焦是将图片文件存放在目录C:\Users\你的帐户名\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_随机生成\LocalState\Assets下。
  • 进入这个路径一看,咦!竟然没有格式,强行用图片软件打开,果然微软这个小心机doge,把类型名搞掉,加上默认隐藏文件扩展名,成功阻止一大批小白把图片扣走
  • 然鹅,这并挡不住咱们倔强的程序员,紧接着又发现一个特性,有时候前一刻去看还有图片,后一刻看就是空文件夹了!由此推测,聚焦在下一批文件来临时会清空这个文件夹,那么我们就需要弄一个东西,把这些图片搞出来。
  • 联想到这个Bash 我就想,虽然界面有点坑,但是可以在其他地方写好脚本,丢到环境里运行不就行了!

怀着这个美好的梦想,踏上了脚本之路,为了兼容两个系统的不同路径表达,着实费了一番功夫。

  • 由于我系统中装了git,所以git Bash 自然成了我的首选开发环境。
  • 我所要的功能是什么呢:
    • 将聚焦文件夹里的所有文件,转换成图片,再移动到自己的文件夹里面去保存,每天定时做几次就行。

上代码

#!/bin/bash
# Created By WuShengXin @ 2016
# 这个脚本依赖 *nix 的 shell 执行环境,可以安装 git 或者 cygwin 来获取环境
# 当然也可以使用 Linux in Windows的功能解决,这个会是最好的解决办法。
#
# 修改这里,用来设定保存路径!修改引号内的内容即可,替换成你先要的存储路径
# 反斜杠记得要写两个
destination="E:\\User-wu\\Media\\Picture\\"
#
# 注: 可以通过传入参数的方式设置聚焦的文件夹路径,但是并不推荐这种做法。
# 除非你想用这个脚本做另外的事情。
# 当前由于 Bash On Windows 尚不完善,故这个脚本无法在其中使用,可以用上面提到的前两种环境运行。
echo "Created By WuShengXin @ 2016, Use it CAREFULLY! Read The Reference above it"
echo "You Can send a real Path to that Script by FIRST PARAMTER, But Not Recommend exclude the other using."
# 检测
cd $destination 2>&1 /dev/null
if [ $? -ne 0 ];
then
    # 这个存储路径是错误,尝试一下*nix格式的路径
    tmp=`echo ${destination/:/} | sed 's/\b[A-Z]/\L&/'`
    tmpcpy="/mnt/${tmp//\\/\/}"
    #echo "Final dest: $tmpcpy"
    if [ -d "$tmpcpy" ];
    then
        #echo "$tmpcpy Exist"
        destination=$tmpcpy
    else
    echo "Bad Destination-Path, Check For Real"
    fi
fi    
if [[ $1 == "" ]];
then
    echo ""
else
    echo "Your Enter is : $1"
fi
# 源路径,即聚焦路径
dir=$1
solid=""
# 固有属性
presolidwin="C:/Users"
presolidnix="/mnt/c/Users"
suffsolid="AppData/Local/Packages"

# 查看系统运行的环境
# 如果是在 Win环境下
if [ -d "$presolidwin" ];
then
    solid="$presolidwin/`whoami`/$suffsolid"
# 如果是在 bash 中
elif [ -d "$presolidnix" ];
then
    for username in `ls $presolidnix`
    do
        solid="$presolidnix/$username/$suffsolid"
        #echo "FOR LOOP: $solid"
        if [ -d "$solid" ];
        then
            #echo ">>>$solid exist<<<"
            break
        fi
    done
# 位置系统环境,退出
else
    echo "Your System Seem to be Nothing with Windows spotlight Function!1"
    exit 1
fi
# 检测,如果是在 bash 中,那么是否有聚焦功能
if [ ! -d "$solid" ];
then
    echo "Your System Seem to be Nothing with Windows spotlight Function!2"
    exit 2 
fi
dirpossible=`ls $solid | grep -e "^Microsoft.Windows.ContentDeliveryManager_"`
# 是否有聚焦这个功能
if [[ $dirpossible == "" ]];
then
    echo "Your Windows Version Does Not Support That Function!"
    exit 1
fi

# 得到完整的聚焦图片存放路径
save=${dir:="$solid/$dirpossible/LocalState/Assets"}
# 进入聚焦文件夹
cd $dir
# 进入聚焦文件夹失败,退出脚本
if [ $? -ne 0 ];
then 
    echo "Bad Dir Path, Check For Real"
    exit 1
fi
# 遍历图片文件
echo ""
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo "Tring To rename the file which is Picture Before, Please Wait..."
echo "         Your Source Dir : $dir"
echo "         Destination Dir : $destination "
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
for file in `ls`
do
    # 测试是否有非标准聚焦存储格式的文件存在
    if [[ $file =~ "." ]];
    then
        echo "Something Unknown has Been Detected: $file"
    else
        cp $file $file.jpg
        # 只要 1920 * 1080 的图片,其他分辨率的被本行过滤。
        # 注 由于 bash 子系统现在对命令的支持尚不完善,故现在无法在 bash 中使用,此处bash
        # 指的是 WSL(Windows Subsystem Linux/Bash on Windows)
        return=`file $file.jpg | awk '{print $(NF-2)}' | grep -e "^1920"`
        if [[ "$return" == "" ]];
        then
            rm $file.jpg
            continue
        fi
        mv $file.jpg $destination
        echo "Success : $file.jpg"
    fi
done
echo "End The Task!"
  • 代码可以去这里下载,复制也行
  • 上面这段代码实现了看起来挺简单的功能,之所以如此,是因为需要兼通两种不同的路径,举个栗子

    • Windows 下的路径E:\your-path\
    • Bash下则是/mnt/e/your-path/
  • 可以看到,这里涉及了环境判断和路径转换的操作,尤其是在聚焦文件夹这里有许多坑

    • WSL系统,是一个完整的子系统,这意味着它有自己的用户名,即考虑通用性,无法使用whoami来获取用户名,以此构造路径。否则
    • WSL里跑的脚本和在git Bash里跑的就不一样了,导致WSL里的脚本所获取的路径不正确
    • 使用最原始的方法来解决这个问题:

      for username in `ls $presolidnix`
      
    • 遍历所有用户的名称,找到第一个拥有这个文件夹的就行了。这么久解决了不同系统,不同用户名的问题。
  • 以上是坑点之一,另一个最致命的坑点在于命令的阉割

    • 在最后一步操作中,我们需要过滤文件的分辨率,即只要1920*1080而不要其他分辨率的,按道理来说使用一个file命令配合awk抽取和grep匹配,可以轻松完全这个任务,但是
    • 万万没想到WSLfile竟然无法显示分辨率!
    • 要么去掉过滤这一步,把所有图片都拷贝过来,但是我没法容忍,所以就这样放弃Bash On Windows了,就当踩个坑
    • 这个脚本很完美的运行在Git Bash中,如果不介意分辨率的话,可以将那六行注释掉,也能很好的跑在WSL下。

最后

  • 还是不得不说,本次体验不太好,还是继续用虚拟机吧。