Ubuntu开机自启服务systemd.service配置教程(Ubuntu服务)(Linux服务)upstart
文章目录
- 为什么要将程序配置成服务?
- 1. 自动启动
- 2. 后台运行
- 3. 定时重启
- 4. 简化管理
- 5. 整合系统
- 版本支持
- 1. Ubuntu 14.04及更早版本:使用`upstart`作为默认的init系统
- /etc/rc.local
- 旧版本
- 新版本
- 2. Ubuntu 15.04到16.04版本:默认使用`systemd`作为init系统,但仍然兼容`upstart`
- 3. Ubuntu 16.10及更高版本:默认使用`systemd`作为init系统
- 总结
- 开机自启服务原理
- 配置步骤
- 1. 创建配置文件
- 2. 编辑配置文件
- 3. 拷贝配置文件
- 4. 启用服务
- 5. 启动服务
- 6. 停止服务
- 7. 禁用服务
- 配置项解释
- 配置父项
- 配置子项
- `[Unit]`配置子项
- - `Description`:用于设置服务的描述信息。
- - `Requires`:用于指定服务所依赖的其他服务。
- - `After`:用于指定服务启动的顺序,可以设置在哪些服务之后启动。
- - `Before`:用于指定服务启动的顺序,可以设置在哪些服务之前启动。
- `[Service]`配置子项
- - `ExecStart`:用于指定服务的启动命令。
- - `WorkingDirectory`:用于指定服务的工作目录。
- - `Environment`:用于设置服务的环境变量。
- - `User`:用于指定服务运行的用户。
- - `Group`:用于指定服务运行的用户组。
- `[Install]`配置子项
- - `WantedBy`:用于指定服务在哪些目标(target)下启动。
- - `RequiredBy`:用于指定哪些目标(target)依赖于该服务。
- systemd官方文档(systemd.service完整配置选项)
- systemd支持在/etc/systemd/system创建子目录,便于我们方便管理我们的.service文件
- vscode相关插件:Systemd Helper
- 使用软链接链接systemd配置文件
为什么要将程序配置成服务?
我们在linux系统下启动一个程序,一般用一条命令,或者执行一个脚本就行了,那么,为什么还要将程序配置成服务?这样做有什么好处?
1. 自动启动
配置成服务后,程序将在系统启动时自动启动,无需手动操作。这样可以确保程序在系统重启后能够自动运行,避免因为人为疏忽或其他原因导致程序未能启动。
2. 后台运行
配置成服务后,程序将以后台进程的方式运行,不会占用终端或用户会话。这样可以确保程序在后台持续运行,即使用户注销或关闭终端。
3. 定时重启
通过配置服务,可以设置服务在异常退出时自动重启。这样可以提高程序的稳定性,确保在出现问题时能够及时恢复运行。
4. 简化管理
配置成服务后,可以使用系统工具(如systemctl)来管理服务,如启动、停止、重启、查看状态等。这样可以方便地管理和监控程序的运行状态。
5. 整合系统
配置成服务后,程序可以与系统的其他服务和组件进行整合。例如,可以设置服务的依赖关系,确保在其他服务启动之前先启动该服务;还可以将服务与日志记录、监控系统等集成,方便管理和故障排查。
版本支持
在不同的Ubuntu版本中,配置开机自启服务的方式可能会有所不同。以下是几个常见的Ubuntu版本和它们支持的开机自启服务类型。本文主要讲解Ubuntu 16.10及更高版本,使用systemd作为init系统的服务开机自启方式。
1. Ubuntu 14.04及更早版本:使用upstart作为默认的init系统
可以创建一个.conf文件来配置开机自启服务,然后将它放在/etc/init/目录下。
/etc/rc.local
旧版本
rc.local是一种在Ubuntu中配置开机自启服务的方式,它属于早期版本的init系统。具体来说,rc.local是在Ubuntu 14.04及更早版本中使用的方式,使用的是upstart作为默认的init系统。
rc.local是一个脚本文件,位于/etc/rc.local。你可以在该文件中添加要在系统启动时执行的命令或脚本。这些命令或脚本将在系统启动时自动执行。
以下是使用rc.local配置开机自启服务的步骤:
-
打开
rc.local文件:sudo nano /etc/rc.local -
在文件中添加你要执行的命令或脚本。例如,如果要启动一个名为
my_service的服务,可以添加以下内容:/path/to/your/service注意,命令或脚本必须是可执行的。
-
保存并关闭文件。
-
确保
rc.local文件具有可执行权限:sudo chmod +x /etc/rc.local -
重启系统,服务将在系统启动时自动执行。
需要注意的是,rc.local方式在较新的Ubuntu版本中已经不再推荐使用,因为它是基于旧的upstart系统。对于使用systemd作为init系统的较新版本的Ubuntu,建议使用systemd的方式来配置开机自启服务。
新版本
在一些较新的Ubuntu版本中,如Ubuntu 16.04及更高版本,rc.local文件默认是被禁用的,因为这些版本使用systemd作为默认的init系统。systemd不会自动执行rc.local文件中的内容。
为了在这些版本中使用rc.local文件,可以通过配置rc-local.service来实现。rc-local.service是一个systemd服务单元,用于在系统启动时执行rc.local文件中的内容。
以下是配置rc-local.service的步骤:
-
创建
rc-local.service文件:sudo nano /etc/systemd/system/rc-local.service -
在文件中添加以下内容:
[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local[Service] ExecStart=/etc/rc.local start Type=forking TimeoutSec=0 RemainAfterExit=yes[Install] WantedBy=multi-user.target -
创建
rc.local文件:sudo nano /etc/rc.local -
在
rc.local文件中添加要执行的命令或脚本。 -
保存并关闭文件。
-
设置
rc.local文件的权限:sudo chmod +x /etc/rc.local -
启用
rc-local.service:sudo systemctl enable rc-local.service -
启动
rc-local.service:sudo systemctl start rc-local.service
rc.local文件中的内容将在系统启动时自动执行。
对于较新的Ubuntu版本,使用rc.local和rc-local.service的方式可能不是最佳实践。推荐使用systemd的方式来配置开机自启服务,以便与当前的init系统保持一致。
2. Ubuntu 15.04到16.04版本:默认使用systemd作为init系统,但仍然兼容upstart
可以使用upstart的方式来配置开机自启服务,或者使用systemd的方式。
3. Ubuntu 16.10及更高版本:默认使用systemd作为init系统
可以使用systemd的方式来配置开机自启服务。
总结
systemd是目前主流的init系统,大多数Ubuntu版本都支持使用systemd来配置开机自启服务。但是,对于旧版本的Ubuntu,可能需要使用upstart来配置开机自启服务。
开机自启服务原理
以使用systemd作为系统初始化的管理器为例。systemd是一个Linux系统和服务管理器,它负责启动、停止和管理系统中的各种服务。
当系统启动时,systemd会读取/etc/systemd/system/目录下的服务配置文件,并根据配置文件中的指令来启动相应的服务。配置文件中的ExecStart字段指定了要执行的命令或脚本,WorkingDirectory字段指定了命令或脚本的工作目录。
通过使用systemctl enable命令,我们告诉systemd将该服务配置文件链接到系统的默认目标(default target),使得该服务在系统启动时自动启动。
当系统启动时,systemd会按照配置文件中的指令来启动服务。如果服务成功启动,systemd会将服务的状态标记为"active"。如果服务启动失败,systemd会将服务的状态标记为"failed"。
通过使用systemctl start命令,我们可以手动启动服务。而使用systemctl stop命令可以停止服务。
通过使用systemctl disable命令,我们可以禁用服务,使得该服务在系统启动时不会自动启动。
总结:使用systemd来管理服务的启动和停止,通过配置服务配置文件并将其链接到系统的默认目标,使得服务在系统启动时自动启动。
配置步骤
以systemd作为init系统的服务开机自启方式为例。下面是配置开机自启服务的步骤:
1. 创建配置文件
创建一个服务配置文件,以.service为后缀,比如my_service.service。
2. 编辑配置文件
使用文本编辑器打开该文件,并添加以下内容:
[Unit]
Description=My Service
After=network.target[Service]
ExecStart=/path/to/your/script.sh
WorkingDirectory=/path/to/your/working/directory[Install]
WantedBy=default.target
在上面的配置中,需要替换/path/to/your/script.sh为你要在开机时运行的脚本的路径,/path/to/your/working/directory为脚本的工作目录。
3. 拷贝配置文件
将该服务配置文件移动到/etc/systemd/system/目录下:
sudo mv my_service.service /etc/systemd/system/
4. 启用服务
使用以下命令启用服务:
sudo systemctl enable my_service
5. 启动服务
使用以下命令启动服务:
sudo systemctl start my_service
现在,该服务将会在每次开机时自动启动。
6. 停止服务
如果需要停止服务,可以使用以下命令:
sudo systemctl stop my_service
7. 禁用服务
如果需要禁用服务,可以使用以下命令:
sudo systemctl disable my_service
配置项解释
配置父项
在systemd中,配置文件通常使用.service扩展名,并且使用INI格式。一个.service文件可以包含以下三个配置项:
-
[Unit]:这个配置项定义了服务的基本属性,如服务的描述、依赖关系、启动顺序等。在这个配置项中,可以设置服务的名称、描述、依赖关系、启动顺序等。 -
[Service]:这个配置项定义了服务的具体执行方式,如服务的启动命令、环境变量、工作目录等。在这个配置项中,可以设置服务的启动命令、环境变量、工作目录等。 -
[Install]:这个配置项定义了服务的安装方式,如服务的启动级别、启动顺序等。在这个配置项中,可以设置服务的启动级别、启动顺序等。
这三个配置项分别定义了服务的基本属性、具体执行方式和安装方式。
除了[Unit]、[Service]和[Install]之外,systemd还支持其他一些配置项,用于进一步定义和配置服务。以下是一些常用的配置项:
-
[Path]:用于监控文件或目录的变化,并在变化发生时触发服务的启动、停止或重启。 -
[Timer]:用于定义定时器,可以在指定的时间间隔或特定时间点触发服务的启动、停止或重启。 -
[Socket]:用于定义套接字,可以监听指定的网络端口或UNIX域套接字,并在有连接请求时触发服务的启动。 -
[Mount]:用于定义挂载点,可以在指定的文件系统挂载或卸载时触发服务的启动、停止或重启。 -
[Automount]:用于定义自动挂载点,可以在访问指定的文件系统路径时自动挂载该文件系统。 -
[Swap]:用于定义交换空间,可以在指定的交换文件或分区被启用或禁用时触发服务的启动、停止或重启。
配置子项
[Unit]配置子项
- Description:用于设置服务的描述信息。
- Requires:用于指定服务所依赖的其他服务。
- After:用于指定服务启动的顺序,可以设置在哪些服务之后启动。
- Before:用于指定服务启动的顺序,可以设置在哪些服务之前启动。
[Service]配置子项
- ExecStart:用于指定服务的启动命令。
- WorkingDirectory:用于指定服务的工作目录。
- Environment:用于设置服务的环境变量。
- User:用于指定服务运行的用户。
- Group:用于指定服务运行的用户组。
[Install]配置子项
- WantedBy:用于指定服务在哪些目标(target)下启动。
WantedBy是systemd服务配置文件中的一个选项,用于指定服务所属的启动级别(target)。启动级别是一组定义了系统启动过程中要启动的服务的目标单元的集合。
在systemd中,启动级别由target单元来表示。每个target单元都是一组相关的服务单元的集合,用于定义系统在不同阶段启动时应该启动哪些服务。例如,multi-user.target是一个常见的启动级别,用于表示系统已经启动到多用户模式,此时应该启动所有与用户交互相关的服务。
WantedBy选项用于指定服务所属的启动级别。它接受一个目标单元的名称作为参数。当你将服务配置文件放置在/etc/systemd/system/目录下,并使用systemctl enable命令启用服务时,systemd会根据WantedBy选项中指定的目标单元,将服务添加到相应的启动级别中。
在上面的例子中,WantedBy=multi-user.target表示该服务应该属于multi-user.target启动级别,即系统已经启动到多用户模式时应该启动该服务。
在systemd中,有以下几个常见的启动级别(target):
poweroff.target:系统关机时的目标单元。rescue.target:用于系统救援的目标单元,提供了一个最小的功能集合,用于修复系统问题。multi-user.target:多用户模式的目标单元,用于正常的多用户操作。graphical.target:图形界面模式的目标单元,用于启动图形界面环境。reboot.target:系统重启时的目标单元。
除了上述常见的启动级别,还有其他一些特定的启动级别,如network.target(网络启动完成后的目标单元)、default.target(默认目标单元,通常是multi-user.target或graphical.target)等。
对于普通程序来说,通常会将其配置为属于multi-user.target或graphical.target这样的启动级别,以便在系统启动到多用户模式或图形界面模式时自动启动。你可以根据你的需求选择适合的启动级别。
- RequiredBy:用于指定哪些目标(target)依赖于该服务。
systemd官方文档(systemd.service完整配置选项)
https://www.freedesktop.org/software/systemd/man/systemd.service.html
systemd支持在/etc/systemd/system创建子目录,便于我们方便管理我们的.service文件
systemd会递归遍历/etc/systemd/system目录下的所有.service文件以及子目录中的.service文件。这意味着可以在/etc/systemd/system目录下创建子目录,并在子目录中放置您的服务配置文件。
例如,如果在/etc/systemd/system目录下创建了一个名为my-service的子目录,并将服务配置文件my-service.service放置在该子目录中,systemd仍然能够找到并管理该服务。
这种递归遍历的机制使得您可以更好地组织和管理多个服务的配置文件,而不会造成混乱。
vscode相关插件:Systemd Helper
可以方便我们编辑systemd配置文件:


使用软链接链接systemd配置文件
可以将.service文件创建为软链接,链接到实际文件。这样做可以使服务配置文件保持在原始位置,同时在/etc/systemd/system目录下创建一个链接,以便systemd能够找到并管理该服务。
以下是创建软链接的步骤:
-
在
/etc/systemd/system目录下创建一个软链接,链接到实际文件。例如,假设实际文件位于/path/to/my-service/my-service.service,可以使用以下命令创建软链接:sudo ln -s /path/to/my-service/my-service.service /etc/systemd/system/ -
确保软链接的文件权限正确设置。一般来说,软链接的所有者应为
root用户,权限应为644:sudo chown root:root /etc/systemd/system/my-service.service sudo chmod 644 /etc/systemd/system/my-service.service
通过这种方式,服务配置文件将保持在原始位置,而软链接将位于/etc/systemd/system目录下,使systemd能够找到并管理该服务。这样做的好处是,当需要修改或更新服务配置文件时,只需在原始位置进行操作,而不需要修改软链接。
相关文章:
Ubuntu开机自启服务systemd.service配置教程(Ubuntu服务)(Linux服务)upstart
文章目录 为什么要将程序配置成服务?1. 自动启动2. 后台运行3. 定时重启4. 简化管理5. 整合系统 版本支持1. Ubuntu 14.04及更早版本:使用upstart作为默认的init系统/etc/rc.local旧版本新版本 2. Ubuntu 15.04到16.04版本:默认使用systemd作…...
大数据课程E4——Flume的Channel
文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Channel的作用和配置; ⚪ 掌握Channel的使用方法; ⚪ 掌握Channel的File Channel; ⚪ 掌握Channel的JDBC Channel; ⚪ 掌握Channel的Spillable Memory Channel; 一、Memory Ch…...
es6中的Map和Set数据结构
Map Map对象可以用于保存键值对 1.创建 一个Map对象 const map new Map() 2.Map的一些方法 set(key,value):通过键值对向Map对象中添加元素get(key):通过建拿到对应的值size:返回Map对象中所包含的键值对的个数has(key):判断Map对象中是否有对应的key,返回一个…...
MyBatis 框架基本的增删改查
提示:写代码要严谨 文章目录 前言前期准备MyBatis CRUD操作流程增加功能删除功能修改功能查询功能#{} 占位符${} 占位符两种占位符的区别❗ 映射文件总结❗ mapper 代理方式实现CRUDmapper代理开发规范增加功能删除功能修改功能查询功能 前言 提示:myba…...
Javascript--JSON
什么是 JSON? JavaScript中的JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于存储和表示结构化的数据。JSON使用键值对的方式组织数据,并支持基本数据类型(字符串、数字、布尔值、数组和对象&…...
Rust: error: failed to run custom build command for `openssl-sys v0.9.71`
error: failed to run custom build command for openssl-sys v0.9.71 解决 windows : openssl 不要选Light版 设置环境变量 cmd: set OPENSSL_DIR“C:\Program Files\OpenSSL-Win64” OPENSSL_DIR:C:\Program Files\OpenSSL-Win64 linux:…...
Excel修改日期格式,改变日期的筛选方式
我们有两列日期数据: 左边这一列筛选会显示: 右边这一列筛选会显示: 修改格式,将【日期1】改为【日期2】 将【日期1】的格式修改为文本格式即可 修改格式,将【日期2】改为【日期1】 选中日期2,点击【数据…...
【RabbitMQ(day2)】默认(直连)交换机的应用
文章目录 一、第一种模型(Hello World)二、第二种模型(work queue)自动确认机制的后果和公平分配 三、阐述默认交换机 这篇博客是以下资料学后的总结: 不良人的RabbitMQ的教学视频 官方启动教程 RabbitMQ中文文档 一、…...
谷粒商城第八天-商品服务之品牌管理的整体实现(直接使用逆向生成的代码;含oss文件上传)
目录 一、总述 二、前端部分 2.1 创建好品牌管理菜单 2.2 复制组件 编辑2.3 复制api 编辑 2.4 查看效果 编辑2.5 需要优化的地方 2.6 具体优化实现 2.6.1 优化一:将表格的状态列(这里是是否显示列)修改为开关ÿ…...
阿里云率先荣获容器集群稳定性先进级认证
7 月 25 日,由中国信通院发起的“2023 稳保体系”评估结果在可信云大会现场公布,阿里云容器服务 ACK 成为首批通过“云服务稳定运行能力-容器集群稳定性”评估的产品,并荣获“先进级”认证。 云原生技术正在激活应用构建新范式,构…...
【SpringBoot笔记37】SpringBoot基于@ServerEndpoint、@OnMessage等注解的方式集成WebSocket
这篇文章,主要介绍SpringBoot基于@ServerEndpoint、@OnMessage等注解的方式集成WebSocket。 目录 一、基于注解集成WebSocket 1.1、WebSocket常见注解 1.2、创建WebSocket服务端 1.3、配置ServerEndpointExpor...
PyTorch(安装及卸载)
目录 1. 安装 2. 卸载 参考文献 为什么用PyTorch:简单来说,19年之前tensorflow是大哥,19年tensorflow和PyTorch双龙并行,20年之后PyTorch一往无前。宗旨,哪个用的人多用哪个。 1. 安装 1. 先打开Anaconda Prompt&…...
webScoket
webScoket是什么? 支持端对端通讯可以由客户端发起,也可以有服务端发起用于消息通知、直播间讨论区、聊天室、协同编辑等 做一个简单的webScoket 客户端配置: 1、新建一个页面叫web-scoket.html <!DOCTYPE html> <html lang"…...
【C语言初阶(20)】调试练习题
文章目录 前言实例1实例2 前言 在我们开始调试之前,应该有个明确的思路;程序是如何完成工作的、变量到达某个步骤时的值应该是什么、出现的问题大概会在什么位置。这些东西在调试之前都需要先确认下来,不然自己都不知道自己在调试个什么东西…...
MicroPython ESP32网页实时更新DHT11数据显示
MicroPython ESP32网页实时更新DHT11数据显示 📌相关篇《MicroPython ESP32 读取DHT11温湿度传感器数据》📍《【Micropython esp32/8266】网页点灯控制示例》 ✨本例综合以上两篇文章内容实现:在本地网页中显示DHT11温度传感器数据。可以做到…...
JavaWeb之HTML基础篇(一)
系列文章目录 HTML基础篇(一) 文章目录 系列文章目录HTML基础篇(一)[TOC](文章目录) 前言一、HTML简介1.1介绍1.2HTML文件的书写规范1.3 HTML标签介绍1.4 HTML常见的标签 二、CSS的简介2.1css技术介绍2.2 CSS与HTML结合的三种方式…...
TVM_深度学习编译器
TVM_深度学习编译器 TVM所做的是要比传统compiler更偏上层的,你可以把它理解成source-to-source compiler,需要其他的后端(backend)来生成最后的指令。比如当编译的Target是Intel CPU时,翻译的顺序是Relay IR -> TVM IR/ Halide IR -> LLVM IR,之后交给LLVM生成最后…...
Flutter InheritedWidget 共享状态管理
InheritedWidget和React中的context功能类似,可以实现跨组件数据的传递。 定义一个共享数据的InheritedWidget,需要继承自InheritedWidget 这里定义了一个of方法,该方法通过context开始去查找祖先的HYDataWidget(可以查看源码查找…...
什么是反射?Java反射?反射的优缺点
目录 什么是反射(Reflection )?Java反射?反射的优缺点获取Class对象的三种方式:java反射技术的应用场景 什么是反射(Reflection )? 主要是指程序可以访问、检测和修改它本身状态或行…...
小红书2020校招测试开发后端笔试题卷三
//完全背包求组合数 #include <iostream> #include<vector> #include<set> #include<map> #include<algorithm> using namespace std; int value[300]; // vector<int>vis; // vector<int>vis1; map<vector<int>,int>m…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
比特币:固若金汤的数字堡垒与它的四道防线
第一道防线:机密信函——无法破解的哈希加密 将每一笔比特币交易比作一封在堡垒内部传递的机密信函。 解释“哈希”(Hashing)就是一种军事级的加密术(SHA-256),能将信函内容(交易细节…...
项目进度管理软件是什么?项目进度管理软件有哪些核心功能?
无论是建筑施工、软件开发,还是市场营销活动,项目往往涉及多个团队、大量资源和严格的时间表。如果没有一个系统化的工具来跟踪和管理这些元素,项目很容易陷入混乱,导致进度延误、成本超支,甚至失败。 项目进度管理软…...
【大厂机试题解法笔记】矩阵匹配
题目 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式 N M K N*M矩阵 输…...
